Reputation: 13
I'm new to Python and am trying a bunch of different projects to learn. I want to use Turtle to create a game and I found this guy on YouTube who walks through re-creating Space Invaders.
I'm using IDLE and Python 3. The screen and player are created, but nothing happens when I press a key. I have looked up this issue and tried a number of things, but I'm not sure what I'm doing wrong.
The other unusual thing is that each function is run once. I included a print statement in each function to discover this. Why is it running each key press event once, but not binding to my actual keyboard?
import turtle
#Screen setup
screen = turtle.Screen()
screen.bgcolor('black')
screen.title("Space Invaders")
#Create player
player = turtle.Turtle()
player.color('blue')
player.shape('triangle')
player.penup()
player.speed(0)
player.setposition(0, -250)
player.setheading(90)
playerspeed = 15
#Move the player left and right
def move_left():
x = player.xcor()
x -= playerspeed
player.setx(x)
screen.listen()
print("Move left.") #for debugging
def move_right():
x = player.xcor()
x += playerspeed
player.setx(x)
screen.listen()
print("Move right.") #for debugging
#Create keyboard binding
screen.onkey(move_left(), 'Left')
screen.onkey(move_right(), 'Right')
screen.listen()
#Play game
screen.mainloop()
Upvotes: 1
Views: 778
Reputation: 70
I think the guy you found on YouTube might have been using python 2.7 rather than python 3 which would change the keypress commands.
Instead of
screen.onkey(move_left(), 'Left')
screen.onkey(move_right(), 'Right')
screen.listen()
You should use
screen.listen()
screen.onkeypress(move_left, 'Left')
screen.onkeypress(move_right, 'Right')
Upvotes: 0
Reputation: 41905
The problem is with these two lines of code:
screen.onkey(move_left(), 'Left')
screen.onkey(move_right(), 'Right')
You don't want to call move_left()
, you want to pass move_left
to be called by the event handler when the key is pressed:
screen.onkey(move_left, 'Left')
screen.onkey(move_right, 'Right')
By including the parentheses, you pass the return value of move_left()
which is None
, effectively disabling the event instead of enabling it!
Here's a rework of your code with the above fix plus another trick: space invader type games are perfect for taking advantage of the rarely used turtle.settiltangle()
method. This method allows us to make the turtle appear to point vertically, while actually oriented horizontally. So we can simply used forward()
and backward()
to move it across the screen:
from turtle import Screen, Turtle
PLAYER_SPEED = 15
# Move the player left and right
def move_left():
player.backward(PLAYER_SPEED)
def move_right():
player.forward(PLAYER_SPEED)
# Screen setup
screen = Screen()
screen.bgcolor('black')
screen.title("Space Invaders")
# Create player
player = Turtle('triangle')
player.speed('fastest')
player.color('blue')
player.penup()
player.sety(-250)
player.settiltangle(90)
# Create keyboard binding
screen.onkey(move_left, 'Left')
screen.onkey(move_right, 'Right')
screen.listen()
# Play game
screen.mainloop()
Of course, you have to remember when you fire a projectile that your turtle is pointing right and redirect it accordingly!
Upvotes: 1