Daniel Rubinstein
Daniel Rubinstein

Reputation: 13

Turtle is not reacting to onkeypress

I am new in python so I took some time and watched some videos about how to make a simple "snake" game, I was doing everything that dude was saying, but when it came to the keyboard binding something went wrong and I can't move my turtle.. code:https://pastebin.com/GLSRNKLR

import turtle
import time

delay = 0.1
# Screen
wn = turtle.Screen()
wn.title("Snake Game By AniPita")
wn.bgcolor('black')
wn.setup(600, 600)
wn.tracer(0)
# Snake Head
head = turtle.Turtle()
head.speed(0)
head.shape("square")
head.color("white")
head.penup()
head.goto(0, 0)
head.direction = "stop"


# Functions
def go_up():
    head.direction == "up"


def go_down():
    head.direction == "down"


def go_left():
    head.direction == "left"


def go_right():
    head.direction == "right"


def move():
    if head.direction == "up":
        y = head.ycor()
        head.sety(y + 10)
    if head.direction == "down":
        y = head.ycor()
        head.sety(y - 10)
    if head.direction == "left":
        x = head.xcor()
        head.setx(x - 10)
    if head.direction == "right":
        x = head.xcor()
        head.setx(x + 10)


# Keyboard Bindings
wn.onkeypress(go_up(), 'w')
wn.onkeypress(go_down(), 's')
wn.onkeypress(go_left(), 'a')
wn.onkeypress(go_right(), 'd')
wn.listen()
# Main Game
while True:
    wn.update()
    time.sleep(delay)
    move()

wn.mainloop()

Upvotes: 1

Views: 1013

Answers (2)

cdlane
cdlane

Reputation: 41872

@JBernardo is absolutely right about function references vs. function calls (+1).

But, I want to address another issue in your code: the use of while True: and to a lesser extent wn.update() and time.sleep(delay). In an event-driven world like turtle there should never be while True: as control should be turned over to the event handler via the wn.mainloop() call which your code never reaches. To get the time delayed animation you desire, we can use a timer event via wn.ontimer().

Below is your code rewritten to use a timer event and simplify your turning logic:

from turtle import Screen, Turtle

DELAY = 100  # milliseconds

# Screen
wn = Screen()
wn.title("Snake Game By AniPita")
wn.bgcolor('black')
wn.setup(600, 600)

# Snake Head
head = Turtle('square')
head.speed('fastest')
head.color('white')
head.setheading(1)  # magic token for no motion
head.penup()

# Functions
def go_up():
    head.setheading(90)

def go_down():
    head.setheading(270)

def go_left():
    head.setheading(180)

def go_right():
    head.setheading(0)

def move():
    if head.heading() % 90 == 0:
        head.forward(10)
    wn.ontimer(move, DELAY)

# Keyboard Bindings
wn.onkeypress(go_up, 'w')
wn.onkeypress(go_down, 's')
wn.onkeypress(go_left, 'a')
wn.onkeypress(go_right, 'd')
wn.listen()

# Main Game
move()

wn.mainloop()

The use of while True: potentially block some of the input events you want to receive from your player.

Upvotes: 1

JBernardo
JBernardo

Reputation: 33397

You want to pass function references to the onkeypress function so it will call it on demand.

Therefore, you need to drop the function calls e.g.:

wn.onkeypress(go_up(), 'w')

should be:

wn.onkeypress(go_up, 'w')

Upvotes: 2

Related Questions