First, we got to understand the basics.
In order for the user to be able to interact with the turtle through key presses, we need to let the window listen for key presses. Since your screen is named wn
, that can be done simply by calling wn.listen()
.
Now that the turtle graphics are listening for key presses, how will you tell the program to do something through key presses? Functions! Let's say you want a new turtle to be created every time a key is pressed; you will need to define a function like so (you can use lambda
for the function, but for now, let's stick to def
):
def create_new_turtle():
new_turtle = turtle.Turtle()
Keep in mind that you shall not pass any positional arguments into the brackets when defining the function, as you will not be able to pass your arguments in when you use the function, resulting in an TypeError
.
Now, let's get into how we can actually call these function during run-time when a key is pressed. With wn.listen()
initiated, now all you'll need is wn.onkey
, or wn.onkeypress
. Taking the function above, if you want a new turtle to be created every time the user presses the SPACE key:
wn.onkey(create_new_turtle, 'space')
Do you see why we can't pass positional arguments into the function? As you can see, when using the function inside wn.onkey
, we do not call it (as in, we did not add brackets on the right side of the function); wn.onkey
does it for us.
Taking what we've learned, let's see them in action:
import turtle
#Screen
wn = turtle.Screen()
wn.bgcolor("lightblue")
#Turtle Player
spaceship = turtle.Turtle()
spaceship.color("red")
spaceship.penup()
#Constant
speed = 1
def up():
spaceship.setheading(90)
def down():
spaceship.setheading(270)
def left():
spaceship.setheading(180)
def right():
spaceship.setheading(0)
wn.listen()
wn.onkey(up, 'Up')
wn.onkey(down, 'Down')
wn.onkey(left, 'Left')
wn.onkey(right, 'Right')
while True:
spaceship.forward(speed)
Can you guess what this does? It's pretty obvious; when the user hits the 'Up'
arrow, the up
function defined above will be called, when the user hits the 'Down'
arrow, the down
function defined above will be called, an so on.
Defining a whole function for a single command doesn't seem right, and we can't just do
wn.onkey(spaceship.setheading(90), 'Up')
wn.onkey(spaceship.setheading(270), 'Down')
wn.onkey(spaceship.setheading(180), 'Left')
wn.onkey(spaceship.setheading(0), 'Right')
Like in the most upvoted answer, the solution is to use lambda
, where the error causing code right above can be corrected to
wn.onkey(lambda: spaceship.setheading(90), 'Up')
wn.onkey(lambda: spaceship.setheading(270), 'Down')
wn.onkey(lambda: spaceship.setheading(180), 'Left')
wn.onkey(lambda: spaceship.setheading(0), 'Right')
Lastly, if you want your turtle to turn 90
degrees maximum on each turn, you can avoid 180
degree turn with if
statements in the functions (which, as the functions get more advanced, it is better to use def
to define the functions instead of using lambda
):
import turtle
#Screen
wn = turtle.Screen()
wn.bgcolor("lightblue")
#Turtle Player
spaceship = turtle.Turtle()
spaceship.color("red")
spaceship.penup()
#Constant
speed = 1
def up():
if spaceship.heading() != 270:
spaceship.setheading(90)
def down():
if spaceship.heading() != 90:
spaceship.setheading(270)
def left():
if spaceship.heading() != 0:
spaceship.setheading(180)
def right():
if spaceship.heading() != 180:
spaceship.setheading(0)
wn.listen()
wn.onkey(up, 'Up')
wn.onkey(down, 'Down')
wn.onkey(left, 'Left')
wn.onkey(right, 'Right')
while True:
spaceship.forward(speed)
Test run:
