2

I am trying to create a turtle crossing game but every time I run the program neither the screen.listen() gets executed nor the screen.exitonclick() After running the program on clicking on the turtle window it does not close neither the turtle moves forward

import turtle
from turtle import Screen
from player import Player
import time

screen = Screen()
screen.setup(width=600, height=600)
screen.tracer(0)

player = Player()

screen.listen()
screen.onkey(player.go_up(), "Up")

turtle.TurtleScreen._RUNNING = True
game_is_on = True

while game_is_on:
    time.sleep(0.1)
    screen.update()

screen.exitonclick()

Although I tried adding the ._RUNNING method, yet it does not make any difference

ggorlen
  • 44,755
  • 7
  • 76
  • 106
syeda
  • 21
  • 5
  • 2
    What is the error you're getting? – Shane Gervais Feb 04 '23 at 07:38
  • 1
    Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community Feb 04 '23 at 13:17
  • 1
    Please share the `Player` class. – ggorlen Feb 04 '23 at 14:20
  • 1
    `screen.onkey(player.go_up(), "Up")` Try removing the parentheses after `go_up`. The purpose of onkey is to provide a function that is called _later_, in response to some event. But because you have the parentheses, the function is being called _now_. – John Gordon Feb 04 '23 at 14:49
  • Also, I don't see any connection between `screen` and `player`. How do you expect the player to be displayed on the screen? – John Gordon Feb 04 '23 at 14:52

1 Answers1

0

There are a few issues here:

  1. while game_is_on: is an infinite loop since game_is_on is never changed from True to False. Anything after the loop will never run. Avoid using this pattern; the typical way to make a real-time rendering loop in turtle is ontimer.
  2. turtle.TurtleScreen._RUNNING = True messes with an undocumented internal property. Unless you have an absolute need to, you shouldn't touch internal properties in libraries because you may be corrupting the instance's state and the property can disappear after an update. I'm not sure what you're trying to do here, but either figure out a way using the public API or drop this code entirely if it's not really needed (I don't think it is--I've never used it in a turtle program).
  3. Although the code for Player wasn't posted, screen.onkey(player.go_up(), "Up") is likely incorrect. It invokes the go_up() method immediately and sets its return value, probably None, as the onkey handler. You probably meant screen.onkey(player.go_up, "Up") which doesn't call the method immediately, but instead passes it to the handler so it can be called later on by the turtle library, when the key is pressed.

With a little stub for Player, I'd suggest a setup like:

import turtle


class Player:
    def __init__(self):
        self.turtle = turtle.Turtle()

    def go_up(self):
        self.turtle.setheading(90)
        self.turtle.forward(10)


def tick():
    #### the main loop; move/update entities here ####

    screen.update()
    screen.ontimer(tick, 1000 // 30)


screen = turtle.Screen()
screen.setup(width=600, height=600)
screen.tracer(0)
player = Player()
screen.onkey(player.go_up, "Up")
screen.listen()
tick()
screen.exitonclick()

Now, you don't have any code in tick yet. This is the main update/rendering loop. The player's movement will be jerky because it's directly wired to the keyboard's retrigger mechanism. If this behavior isn't what you want, I suggest reacting to key presses and changing the player's position only inside of tick. See How to bind several key presses together in turtle graphics? for an example of this.

ggorlen
  • 44,755
  • 7
  • 76
  • 106