I'm trying to put in scheduled refreshes for a pong game, so the screen updates after a time interval so the paddles (which I have segmented) move in sync on the screen. What is the functional difference between these two blocks of code? I was trying to get the first one to work but wasn't able to get it to do what I wanted but after some experimenting I landed at the second one which does:
pongscreen.tracer(0)
def balltiming():
pongscreen.update()
time.sleep(0.5)
balltiming()
balltiming()
pongscreen.listen()
pongscreen.mainloop()
This second one works, but functionally they seem pretty much the same in what they're doing. Why doesn't the first one work but this does?
pongscreen.tracer(0)
def balltiming():
pongscreen.update()
pongscreen.ontimer(balltiming, 300)
balltiming()
pongscreen.listen()
pongscreen.mainloop()
CodePudding user response:
The first block is genuinely recursive, so it'll blow the call stack after ~1000 frames on a typical CPython implementation.
The second block isn't recursive; the initial balltiming
function is completely cleared from the call stack after it sets an ontimer
event. Turtle internally calls the next iteration of balltiming
that has been registered as a callback to ontimer
without unbounded stack growth.
If you want to use sleep
manually, use a while
loop rather than recursion. sleep
blocks the thread and is less amenable to precise framerate control, so generally ontimer
is used, however. A consequence of this is that in the first block, pongscreen.listen()
and pongscreen.mainloop()
won't be reached, while in the second version, both will be reached and the main thread will block at pongscreen.mainloop()
; the typical flow for a turtle program.