pythonevent-handlingturtle-graphicspython-turtle

Problem with onkeypress() and listen() in Python Turtle


I have a problem with one function. I use Python 3.7, and when I try to use the onkeypress() function, nothing happens. I try to check it, but the turtle module doesn't react when I press keys.

I try to move my paddle up using the 'w' key. But it doesn't work. Below are my *.py files:

main.py

import elements
import turtle


#Windows settings

window = turtle.Screen()
window.title("Pong game by Kosa")
window.bgcolor('black')
window.setup(width=800, height=600)
window.tracer(0)

paletka_1 = elements.Objects()
paletka_1.paddle_a()
    
window.onkeypress(paletka_1.paddle_a_up(), "w")
window.listen()
while True:
    window.update()

elements.py

import turtle

class Objects:

    def __init__(self):
        #Paddle A

        #self.paddle_b = turtle.Turtle()


        # #Paddle B

        #Ball
        self.ball = turtle.Turtle()

    def paddle_a(self):

        paddle_a_x = -350
        #paddle_a_y = 0
        self.paddle_a = turtle.Turtle()
        self.paddle_a.speed(0)
        self.paddle_a.shape("square")
        self.paddle_a.shapesize(stretch_wid=5, stretch_len=1)
        self.paddle_a.color('green')
        self.paddle_a.penup()
        self.paddle_a.goto(paddle_a_x, 0)

    def paddle_b(self):
        paddle_b_x = -350
        paddle_b_y = 0

        self.paddle_b.speed(0)
        self.paddle_b.shape("square")
        self.paddle_b.shapesize(stretch_wid=5, stretch_len=1)
        self.paddle_b.color('green')
        self.paddle_b.penup()
        self.paddle_b.goto(paddle_b_x, paddle_b_y)

    def ball(self):
        self.ball.speed(0)
        self.ball.shape("square")
        self.ball.color('white')
        self.ball.penup()
        self.ball.goto(0, 0)

    def paddle_a_up(self):
        y = self.paddle_a.ycor()
        y += 20
        self.paddle_a.sety(y)
        print(y)

    def paddle_b_up(self):
        y = self.paddle_b.ycor()
        y += 20
        self.paddle_b.sety(y)

What I get when program starts: I can push keys, but no change in my paddle. Can you find my mistake? I added print(y) in paddle_a_up() just to make sure, that its works. I get the result of print().

It's strange, because there is no error.

enter image description here


Solution

  • This is a common beginner's error when setting event handlers:

    window.onkeypress(paletka_1.paddle_a_up(), "w")
    

    You don't want to call paddle_a_up, you want to pass it on for some other code to call when the event happens:

    window.onkeypress(paletka_1.paddle_a_up, "w")
    

    Try that to see if it works better for you. As far as the rest of your code goes, I've some suggestions:

    window.tracer(0)
    

    Avoid tracer() and update() until your program is working otherwise it'll just complicate the development and debug process. Only add them back if you need them -- if the program works to your satisfaction, leave them out.

    while True:
        window.update()
    

    This loop really should instead be a call to mainloop() to turn control over to tkinter's event handler:

    window.mainloop()
    

    Having member variables and instance methods with the same name is a bad idea:

    self.ball = turtle.Turtle()
    ...
    def ball(self):
    

    Like the rest of Python, one overwrites the other and bad things happen. My reworked versions of your code:

    main.py

    from turtle import Screen
    import elements
    
    # Windows settings
    
    window = Screen()
    window.title("Pong game by Kosa")
    window.bgcolor('black')
    window.setup(width=800, height=600)
    
    paletka_1 = elements.Objects()
    
    window.onkeypress(paletka_1.paddle_a_up, "w")
    
    window.listen()
    window.mainloop()
    

    elements.py

    from turtle import Turtle
    
    class Objects:
    
        def __init__(self):
            # Paddle A
            self.paddle_a = Turtle("square")
            self.init_paddle_a()
    
            # Paddle B
            self.paddle_b = Turtle("square")
            self.init_paddle_b()
    
            # Ball
            self.ball = Turtle("square")
            self.init_ball()
    
        def init_paddle_a(self):
    
            paddle_a_x = -350
    
            self.paddle_a.speed('fastest')
            self.paddle_a.shapesize(stretch_wid=5, stretch_len=1)
            self.paddle_a.color('green')
            self.paddle_a.penup()
            self.paddle_a.setx(paddle_a_x)
    
        def init_paddle_b(self):
            paddle_b_x = 350
    
            self.paddle_b.speed('fastest')
            self.paddle_b.shapesize(stretch_wid=5, stretch_len=1)
            self.paddle_b.color('red')
            self.paddle_b.penup()
            self.paddle_b.setx(paddle_b_x)
    
        def init_ball(self):
            self.ball.speed('fastest')
            self.ball.color('white')
            self.ball.penup()
            self.ball.home()
    
        def paddle_a_up(self):
            y = self.paddle_a.ycor() + 20
            self.paddle_a.sety(y)
    
        def paddle_b_up(self):
            y = self.paddle_b.ycor() + 20
            self.paddle_b.sety(y)
    

    This should now put up a window with paddles on the left and right and a ball in the middle. Click on the window and after you can press "w" to make the left paddle rise up. Now finish the program!

    enter image description here