简体   繁体   中英

Mixing events in a python turtle program

I am trying to write a python turtle program that behaves similarly to a regular event-driven program that uses a game loop. The program tries to mix mouse, keyboard and timer events as is as posted below.

My problem is that python doesn't seem to be able to mix the onkey() events with the ontimer() loop. When run, the program will animate the turtle and the onclick() event will work. The key press isn't even registered until the mouse is first clicked. Then, when the key is pressed to quit, I get a large list of errors in the shell. The bye() method seems to be terminating the program in a brutish fashion and not shutting down elegantly.

I think that I have the commands in the correct order.

Any suggestions will be appreciated!

import turtle

playGround = turtle.Screen()
playGround.screensize(800, 600, 'light blue')

bob = turtle.Turtle()
bob.color('red')
bob.pencolor('red')
bob.ht()

def teleport(x,y):
    bob.goto(x,y)

def quitThis():
    playGround.bye()

def moveAround():
   bob.fd(10)
   bob.rt(15)
   playGround.ontimer(moveAround,30)

playGround.onclick(teleport,btn=1)
playGround.onkey(quitThis,'q')

moveAround()

playGround.listen()
playGround.mainloop()

One problem I see with your code is you need to keep the moveAround() from happening during the teleport() otherwise you get confusing visuals. I find with turtle that it helps to disable the event handler when inside the event hander and reenable it on the way out.

I believe the following will smooth out your events and allow them all to fire at the appropriate time. I've added a state variable to help control the activity:

from turtle import Turtle, Screen

def teleport(x, y):
    global state

    playGround.onclick(None)  # disable handler inside handler

    if state == "running":
        state = "teleporting"
        bob.goto(x, y)
        state = "running"

    if state != "quitting":
        playGround.onclick(teleport)

def quitThis():
    global state

    state == "quitting"

    playGround.onkey(None, 'q')

    playGround.bye()

def moveAround():
    if state == "running":
        bob.fd(10)
        bob.rt(15)

    if state != "quitting":
        playGround.ontimer(moveAround, 30)

playGround = Screen()
playGround.screensize(800, 600, 'light blue')

bob = Turtle(visible=False)
bob.color('red')

playGround.onclick(teleport)
playGround.onkey(quitThis, 'q')
playGround.listen()

state = "running"

playGround.ontimer(moveAround, 100)

playGround.mainloop()

when the key is pressed to quit, I get a large list of errors in the shell. The bye() method seems to be terminating the program in a brutish fashion

This is typical of turtle. If it really bothers you, see my answer to the question about Turtle window exit errors for one possible solution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM