I can't move two turtle objects independently using the onkeypress function

Viewed 21

I would like to move two different turtle objects(slider_1 and slider_2) upwards and downwards using the onkeypress function from Python's turtle module.

My issue is that when I move slider_1 then I can't move slider_2 without releasing the key for slider_1, and vice-versa. How can I fix my code, so that I can control slider_1 and slider_2 independently, without any pauses in movement.

main.py:

from turtle import Screen, Turtle
from slider import Slider_1, Slider_2
   
HEIGHT = 800
WIDTH = 600
screen = Screen()
screen2 = Screen()
screen.bgcolor("black")
screen.title("PONG")
screen.setup(height=HEIGHT, width=WIDTH)
screen.listen()


slider_1 = Slider_1()
screen.onkeypress(key="Up", fun=slider_1.up)
screen.onkeypress(key="Down", fun=slider_1.down)


slider_2 = Slider_2()
screen.onkeypress(key="w", fun=slider_2.up)
screen.onkeypress(key="s", fun=slider_2.down)


screen.exitonclick()

Slider.py:

from turtle import Turtle

SIZE = 20
SPEED = 10
class Slider(Turtle):

    def __init__(self):
        super().__init__()
        self.penup()
        self.speed("fastest")
        self.shape("square")
        self.shapesize(SIZE)
        self.shapesize(stretch_wid=1, stretch_len=3)
        # self.move = True

    def up(self):
        self.setheading(90)
        if self.ycor() >= 360:
            return
        else:
            self.forward(SPEED)

    def down(self):
        self.setheading(270)
        if self.ycor() <= -360:
            return
        else:
            self.forward(SPEED)


class Slider_1(Slider):

    def __init__(self):
        super().__init__()
        self.color("white")
        self.goto(x=-600 / 2 + SIZE, y=0)
        self.setheading(90)


class Slider_2(Slider):

    def __init__(self):
        super().__init__()
        self.color("blue")
        self.goto(x=600 / 2 - SIZE, y=0)
        self.setheading(90)
1 Answers

The issue here is the hardware key handling. You are only checking for keypress. The keyboard "key repeat" handler only triggers key repeating for the last key that was pressed.

To do what you want, your code is going to get more complicated. You will need to have key press and key release handlers for all 4 of those buttons. The key press handlers will need to set a flag, and the key release handlers will clear the flag. Then, you will need a periodic function (using screen.ontimer) running in a timer that checks the flags: "Is left moving up? Is left moving down? Is right moving up? Is right moving down?" Handle all four possibilities, then exit and wait for the next call.

Related