pythonturtle-graphicspython-turtlepausepausing-execution

Game paused but the paddles in game still moving


Recently I made a Pong game with the turtle module and I'm using this method to pause the game:

# Pause function
game_pause = False
def pause_game():
    global game_pause
    if game_pause:
        game_pause = False
    else:
        game_pause = True
window.listen()
window.onkeypress(pause_game, "p")

But the paddles, via onkeypress() command, still move when I pause the game. Is this method correct for this situation? Or am I just using it wrong? Here's the main game loop if you need more context:

# Main game loop
while True:
    if game_pause:
        window.update()
    else:
        # Ball mover
        ball.setx(ball.xcor() + ball.dx / 5)
        ball.sety(ball.ycor() + ball.dy / 5)

        # Setup keybinding
        window.listen()
        window.onkeypress(paddle_a.move_up, "w")
        window.onkeypress(paddle_a.move_down, "s")
        window.onkeypress(paddle_b.move_up, "Up")
        window.onkeypress(paddle_b.move_down, "Down")

        # Border checking
        if ball.ycor() > 290:
            ball.sety(290)
            ball.dy *= -1

        if ball.ycor() < -290:
            ball.sety(-290)
            ball.dy *= -1

        if ball.xcor() > 390:
            ball.goto(0, 0)
            ball.dx *= -1
            score_a += 1
            pen.clear()
            pen.write(f"Player A: {score_a}  Player B: {score_b}", align="center", font=("Terminal", 22, "normal"))

        if ball.xcor() < -390:
            ball.goto(0, 0)
            ball.dx *= -1
            score_b += 1
            pen.clear()
            pen.write(f"Player A: {score_a}  Player B: {score_b}", align="center", font=("Terminal", 22, "normal"))

        # Paddles collision
        if 350 > ball.xcor() > 340 and paddle_b.ycor() + 50 > ball.ycor() > paddle_b.ycor() - 50:
            ball.setx(340)
            ball.dx *= -1

        if -340 > ball.xcor() > -350 and paddle_a.ycor() + 50 > ball.ycor() > paddle_a.ycor() - 50:
            ball.setx(-340)
            ball.dx *= -1

Solution

  • Your program is structured incorrectly, so I would avoid any quick fix suggestions. Even if they work, you're going to have further problems. Below is my attempt to restructure your code as a proper turtle program. I had to reconstruct missing pieces, so it's not going to look identical:

    from turtle import Screen, Turtle
    
    WIDTH, HEIGHT = 800, 600
    
    FONT = ('Terminal', 22, 'normal')
    
    game_pause = False
    
    class Paddle(Turtle):
        def __init__(self, x):
            super().__init__(shape='square', visible=False)
    
            self.shapesize(stretch_len=2.5, stretch_wid=0.5)
            self.setheading(90)
            self.penup()
            self.setx(x)
    
            self.score = 0
    
            self.showturtle()
    
        def move_up(self):
            if not game_pause:
                self.forward(20)
                screen.update()
    
        def move_down(self):
            if not game_pause:
                self.backward(20)
                screen.update()
    
    class Ball(Turtle):
        def __init__(self):
            super().__init__(shape='circle', visible=False)
    
            self.dx = 3
            self.dy = 2
    
            self.penup()
            self.showturtle()
    
    def pause_game():
        global game_pause
    
        game_pause = not game_pause
    
    # Main game loop
    
    def play():
        if not game_pause:
            # Ball mover
            ball.sety(ball.ycor() + ball.dy)
    
            if ball.ycor() > 290:
                ball.sety(290)
                ball.dy *= -1
            elif ball.ycor() < -290:
                ball.sety(-290)
                ball.dy *= -1
    
            ball.setx(ball.xcor() + ball.dx)
    
            if ball.xcor() > 390:
                ball.goto(0, 0)
                ball.dx *= -1
                paddle_a.score += 1
            elif ball.xcor() < -390:
                ball.goto(0, 0)
                ball.dx *= -1
                paddle_b.score += 1
    
            pen.clear()
            pen.write(f"Player A: {paddle_a.score}  Player B: {paddle_b.score}", align='center', font=FONT)
    
            # Paddles collision
            if 350 > ball.xcor() > 340 and paddle_b.ycor() + 50 > ball.ycor() > paddle_b.ycor() - 50:
                ball.setx(340)
                ball.dx *= -1
            elif -340 > ball.xcor() > -350 and paddle_a.ycor() + 50 > ball.ycor() > paddle_a.ycor() - 50:
                ball.setx(-340)
                ball.dx *= -1
    
            screen.update()
    
        screen.ontimer(play)  # will call play() again after function returns via event loop
    
    screen = Screen()
    screen.setup(WIDTH, HEIGHT)
    screen.tracer(False)
    
    paddle_a = Paddle(-345)
    paddle_b = Paddle(345)
    
    ball = Ball()
    
    pen = Turtle()
    pen.hideturtle()
    pen.sety(270)
    pen.write(f"Player A: {paddle_a.score}  Player B: {paddle_b.score}", align='center', font=FONT)
    
    # Setup keybinding
    screen.onkeypress(pause_game, 'p')
    screen.onkeypress(paddle_a.move_up, 'w')
    screen.onkeypress(paddle_a.move_down, 's')
    screen.onkeypress(paddle_b.move_up, 'Up')
    screen.onkeypress(paddle_b.move_down, 'Down')
    screen.listen()
    
    screen.update()
    
    play()
    
    screen.mainloop()
    

    See if that gives you the pause functionality you desire as well as simplifies your code and leaves room for more features.