Reputation: 23
I'm writing a program that moves the turtle in different directions by pressing down the arrow keys. I want the ability to move it in a particular direction by holding down the respective arrow key instead of pressing it repeatedly. However, when I release the arrow key after holding it down for few seconds, the turtle is moving back a bit instead of stopping immediately. The amount by which it moves back depends on how long I held down the key to move it.
Can you help me to solve this issue or suggest another way to implement this with the turtle module?
Note: I observed that when I hold down the key, the line is not drawn until I release it. I'm not sure if it's expected or related to this issue.
Note 2: I'm using the onkeypress method for handling the "holding down the key" event. I tried using the onkeyrelease(None, arrow_key) method to solve this, but it doesn't work either.
Here is my code:
from turtle import Turtle, Screen
def move_right():
turtle.setheading(0)
turtle.forward(25)
def move_up():
turtle.setheading(90)
turtle.forward(25)
def move_left():
turtle.setheading(180)
turtle.forward(25)
def move_down():
turtle.setheading(270)
turtle.forward(25)
turtle = Turtle()
screen = Screen()
screen.onkeypress(move_right, "Right")
screen.onkeypress(move_up, "Up")
screen.onkeypress(move_left, "Left")
screen.onkeypress(move_down, "Down")
screen.listen()
screen.exitonclick()
Upvotes: 2
Views: 5187
Reputation: 27577
You can use the screen.tracer()
method by setting it to 0
. With that you'll also need to update the screen every time the turtle makes a move:
from turtle import Turtle, Screen
def move_right():
turtle.setheading(0)
turtle.forward(25)
screen.update()
def move_up():
turtle.setheading(90)
turtle.forward(25)
screen.update()
def move_left():
turtle.setheading(180)
turtle.forward(25)
screen.update()
def move_down():
turtle.setheading(270)
turtle.forward(25)
screen.update()
turtle = Turtle()
screen = Screen()
screen.tracer(0)
screen.onkeypress(move_right, "Right")
screen.onkeypress(move_up, "Up")
screen.onkeypress(move_left, "Left")
screen.onkeypress(move_down, "Down")
screen.listen()
screen.exitonclick()
You can also use lambda
functions to shorten your code:
from turtle import Turtle, Screen
def f(num):
turtle.setheading(num)
turtle.forward(25)
screen.Screen.update()
turtle = Turtle()
screen = Screen()
screen.tracer(0)
screen.onkeypress(lambda: f(0), "Right")
screen.onkeypress(lambda: f(90), "Up")
screen.onkeypress(lambda: f(180), "Left")
screen.onkeypress(lambda: f(270), "Down")
screen.listen()
screen.exitonclick()
Do note that it's not optimal to name your Turtle
object turtle
, as it can be confused as the turtle
module.
Upvotes: 0
Reputation: 2145
That took a minute to figure out. Don't know why turtle.forward()
would revert to a previous position after releasing. Python's Turtle module is buggy. It should stay where ya put it, but for whatever reason, it's bubbling back.
This'll do what you expect.
#! /usr/bin/python3
from turtle import Turtle, Screen
turtle = Turtle()
screen = Screen()
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def right():
turtle.setx( turtle.pos()[0] +25 )
def up():
turtle.sety( turtle.pos()[1] +25 )
def left():
turtle.setx( turtle.pos()[0] -25 )
def down():
turtle.sety( turtle.pos()[1] -25 )
screen.onkeypress( right, "Right")
screen.onkeypress( up, "Up")
screen.onkeypress( left, "Left")
screen.onkeypress( down, "Down")
screen.listen()
screen.exitonclick()
## eof ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Edit: oh, it's the setheading()
function being repeated that causes the hangup.
Test for the turtle's heading first, then only set it when required.
#! /usr/bin/python3
from turtle import Turtle, Screen
turtle = Turtle()
screen = Screen()
##~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def right():
if turtle.heading() != 0: turtle.setheading(0)
turtle.forward(25)
def up():
if turtle.heading() != 90: turtle.setheading(90)
turtle.forward(25)
def left():
if turtle.heading() != 180: turtle.setheading(180)
turtle.forward(25)
def down():
if turtle.heading() != 270: turtle.setheading(270)
turtle.forward(25)
screen.onkeypress( right, "Right")
screen.onkeypress( up, "Up")
screen.onkeypress( left, "Left")
screen.onkeypress( down, "Down")
screen.listen()
screen.exitonclick()
## eof ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Upvotes: 3