Clear() clears the entire screen, not only one turtles drawings? - turtle-graphics

I am trying to make a card program with turtle in python and i ran into a problem. I had multiple turtles and tried to clear only the drawing of one to make the illusion of another card coming into play. When i tried clearing only one of the turtles drawings It cleared the entire screen. I have no idea why it cleared it all. Here is a code i wrote to test it out. (I am on Pythonista)
import turtle
t = turtle.Turtle()
b = turtle.Turtle()
for i in range(4):
t.forward(100)
t.left(90)
for i in range(4):
b.backward(100)
b.right(90)
t.clear()

Your code works fine for me under the standard Python distribution. The usual problem would be calling the screen's clear() method instead of the turtle's clear() method but you appear to have done that correctly:
from turtle import Screen, Turtle
screen = Screen()
a = Turtle()
b = Turtle()
for _ in range(4):
a.forward(100)
a.left(90)
for _ in range(4):
b.backward(100)
b.right(90)
a.clear()
screen.exitonclick()
So if the above also fails, it may be an implementation issue with Pythonista's turtle.py library, which I assume is custom as they probably didn't want to replicate tkinter and Tk.

Related

How to get window decorations pixel size in LUA

I am using rdesktop with seamlessrdp. This way I can open Windows apps on my Linux machines. Also I added devilspie2 to the mix so I could control the window decorations. devilspie2 uses lua as its config management. I made everything work. The only issue left is to move the opening (dialog) windows a couple of pixels because the VNC windows will appear as if they had decorations (but without them). I got the code working by hard coding the amount of pixels needed to move. The issue is we have more than one distros here and they have different pixel sizes for their window decorations.
What I want is to GET the decoration size in pixels instead of hard coding them so it will work perfectly for all my distros.
Here is the piece of code that does it atm:
if get_window_class()=="SeamlessRDP" then
undecorate_window();
--x-1 and y-28 works for one distro but for the other I need to use x-6 and y-27
if get_window_type()=="WINDOW_TYPE_DIALOG" then
x, y = xy();
xy(x-1, y-28);
end
end
As you can see from the script. It would be much better if I could somehow call the size of the window decorations and then use them rather than hard coded pixels.
EDIT (ANSWER):
Even though I found the answer before the following post, I wanted to accept it anyways because it did show the right path to follow. I am only further commenting here to show the full answer:
--get x and y's for decorated and non-decorated windows
x1, y1, width1, height1 = get_window_geometry();
x2, y2, width2, height2 = get_window_client_geometry();
--calculate pixels to slide window
xpixel = x2-x1;
ypixel = y2-y1;
--check if class is seamlessrdp
if get_window_class()=="SeamlessRDP" then
undecorate_window();
--if window is a dialog then move it
if get_window_type()=="WINDOW_TYPE_DIALOG" then
xy(x1-xpixel, y1-ypixel);
end
end
devilspie2 provides only two ways to get the window size, get_window_geometry and get_window_client_geometry.
Whereby the last one excludes the window borders. If this does not work for you, you can create a file with a table for all values to make them easily editable. You could also use the window class names as table keys if possible to make the use easier.

How draw a line in a window with wxWidget with erlang?

I try to draw a line in a window with wxWidget in Erlang. I tried:
wx:new(),
Frame = wxFrame:new(wx:null(), ?wxID_ANY, "Hello"),
wxDC:drawLine(50,50),
I get an error:
undefined function wxDC:drawLine/2
I read the documentation here, but I don't understand how to do this:
http://www.erlang.org/doc/man/wxDC.html#drawLine-3
X Windows programming isn't quite that simple, and I'm not quite sure how you are expecting to draw a line with parameters like [50, 50], that's at best a point, and a line needs 2 points, and wxDC:drawLine needs to know where to draw the line too, because you could have many frames.
You can create a frame like this, yes (used -1 instead of the macro because I'm using the shell here):
Wx = wx:new().
Frame = wxFrame:new(wx:null(), -1, "Hello").
Now the important bit, you can't just draw on the frame, you have to register a callback to handle REdrawing. This is because a frame can be covered up at any point by other windows, or because you minimise it, resize it, etc. In fact you don't necessarily need to handle a REdraw for all those cases, but you get the idea.
So, this is not the most efficient, because it performs a redraw regardless of the event, by responding to ANY paint event by drawing a line, but obviously that will do the job:
wxFrame:connect(Frame, paint, [{callback,
fun(_Evt, _Obj) ->
io:format("paint~n"),
DrawContext = wxPaintDC:new(Frame),
wxDC:drawLine(DrawContext, {50, 50}, {150,100}),
wxPaintDC:destroy(DrawContext)
end
}]).
I added the io:format in there so you can see that it is being called when you interact with the window, or some other window interacts with it, because without the io:format call it's a bit invisible in its effect, other than making sure there's always a line in your window.
I also used a draw context. I won't go into it here, I'm afraid it's just one of a load of things you need to learn about X Windows programming, but basically, just be aware for now, you need to have a draw context for your frame, and use that to actually draw with.
One last thing, you need to actually display the frame, if you want to see it, like this:
wxFrame:show(Frame).
Now you should see a window, with a line.
Michael's answer tells you how to do what you want to do, so let me address the confusion about the error
message.
In Erlang, functions that have the same name but different number of arguments are considered separate functions. The number of arguments is called the "arity", and is sometimes indicated as e.g. /2 after the function name.
Your code is calling wxDC:drawLine with two arguments, but you get an error saying that wxDC:drawLine/2 is undefined. In the documentation, you can see that the function you want is wxDC:drawLine/3, which takes three arguments (the first being the draw context, and the second and third being the points between which you want to draw a line).

Lua tables and screen coordinates. For every {x} at y do

I'm having a little curious sense of art in programming at the moment. And I want to script my Autotouch App on my iOS to generate Pixel Art inside of another app.
I was doing this previously by typing in code to tap at the screen at one coordinate, I did this 2000+ times and it got the job done. But there should be a better, smarter way to get it done.
My test image is going to be very symetrical to make things easy.
There is a code in the Lua app that I'm using to simply tap on the screen,
tap(x, y)
But I want to set this up like:
tap({xTable}, y)
But I'm not sure if that will "tap" at each x coordinate that I've listed for the y variable.
I want to paint a pixel at one very specific coordinate, and then step 5 pixels away and paint the next one, and repeat that until the end of the line.
Is this at all possible or am I reaching beyond the language capabilities?
Edit: for some reason my phone is not blocking code when I'm asking a question, if someone sees this and wants to edit, I would be grateful.
Is this at all possible or am I reaching beyond the language capabilities?
Not even close. I recommend you read Programming in Lua.
tap({xTable}, y)
But I'm not sure if that will "tap" at each x coordinate that I've listed for the y variable.
Why are you not sure? Did you not write it? If not, you can trivially write it yourself given tap:
function tapxs(xs, y)
for i,x in ipairs(xs) do
tap(x,y)
end
end
...
tapxs({10,20,30,40}, 10) -- tap at 10,10; 20,10; 30,10; etc.
I want to paint a pixel at one very specific coordinate, and then step 5 pixels away and paint the next one, and repeat that until the end of the line.
What is "the line"? Is it purely horizontal? You could write:
function tapHorizontally(startX, maxX, y, increment)
for x=startX,maxX,increment do
tap(x,y)
end
end
...
tapHorizontally(10,100,20,5) -- tap from 10,20 to 100,20 in 5 pixel increments
Of course, that's a bizarrely specific function. You'd typically write something that takes a starting x,y and ending x,y and draws between them, so you can support horizontal, vertical, diagonal lines all with the same function, but that requires more math.
The bottom line is: Lua is a full blown, powerful, high level programming language. It could be used to write the very app you're tapping on, or the app you're using to generate taps, so the limits are going to be your knowledge of programming/algorithms/math/etc.

colour detection bot

I want to create a script to automatically click on a moving target on a game.
To do this I want to check colours on the screen to determine where my target is and then click him, repeating this if he moves.
I'm not skilled at programming and there might be an easier solution to what I have proposed below:
1/Split the screen into equal tiles - size of tile should represent the in game object.
2/Loop through each pixel of each tile and create a histogram of the pixel colours.
3/If the most common recorded colour matches what we need, we MIGHT have the correct tile. Save the coords and click the object to complete task
4/Every 0.5 seconds check colour to determine if the object has moved, if it hasnt, keep clicking, if it has repeat steps 1, 2 and 3.
The step I am unsure of how to do technically is step 1. What data structure would I need for a tile? Would a 2D array suffice? Store the value of each colour in this array and then determine if it is the object. Also in pseudo how would I split the screen up into tiles to be searched? The tile issue is my main problem.
EDIT for rayryeng 2:
I will be using Python for this task. This is not my game, I just want to create a macro to automatically perform a task for me in the game. I have no code yet, I am looking more for the ideas behind making this work than actual code.
3rd edit and final code:
#!/usr/bin/python
import win32gui, win32api
#function to take in coords and return colour
def colour_return(x,y):
colours = win32gui.GetPixel(win32gui.GetDC(win32gui.GetActiveWindow()), x,y)
return colours
def click(x,y):
win32api.SetCursorPos((x,y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN,x,y,0,0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP,x,y,0,0)
#variable declaration
x = 1
y = 1
pixel_value = []
colour_found = 0
while x < 1600:
pixel_value = colour_return(x,y)
if pixel_value == 1844766:
click(x,y)
x=x+1
#print x
print y
if x == 1600:
y=y+1
x=1
#print tile
pixel_value = 0
This is the final code that I have produced. It works but it is incredibly slow. It takes 30 seconds seconds to search all 1600 pixels of y=1. I guess it is my method that is not working. Instead of using histograms and tiles I am now just searching for a colour and clicking the coordinates when it matches. What is the fastest method to use when searching an entire screen for a certain colour? I've seen colour detection bots that manage to keep up every second with a moving character.

XNA 4.0: How to remove text after drawn to screen?

Good day everyone.
I'm trying to draw the text "Pass Complete!" to screen with this code:
spriteBatch.DrawString(font, "PASS COMPLETE!", new Vector2(30, 130), Color.White);
Which does fire off the proper IF statement. However, how do I go about then removing that text from the screen? I'm really not sure at all where to go on from here and my instructor wants me to google the answer or find it in textbook. I have been all over my XNA textbook and I have found no outlet to removing that text.
Thanks for any and all help.
Update:
protected override void Draw(GameTime gameTime)
I have the IF statement included in here. Basically it checks collision with p_Receiver and if it the bool checks out, it draws the DrawString. Should I maybe be looking at this from a different angle?
Final:
I went ahead with the following as the answer and it's working better then before. :)
if (PassInfo == 3) {
(timer code)
(IF timer not "used up" then run the draw)
Working good for now.
I appreciate it.
I'm doing this by function that add text with some parameters into generic list. and then i update and draw items from that list. in pseudo code:
function addText(text,position,duration)
texts.add(new t(text,position,duration))
end function
function updateText()
for each t as text in texts.findall(where t.active)
t.duration -= 1
if t.duration < 0 then t.active = false
next
end function
function drawText()
for each t as text in texts.findall(where t.active)
//draw it
next
end function
so by this you can add unlimited number of texts on different position and duration on screen.
A lot of games redraw the entire window / screen each time through the draw cycle so there's a distinct chance that the solution to removing it is simply to stop drawing it.
i.e. have your if condition not draw the text when it is no longer required.
If, on the other hand, you've some more complex drawing logic that only draws portions of the window / screen that need updating then you'll need to include logic to redraw that part of the screen that contained the text once it is no longer needed.

Resources