Python - moving turtle on the y-axis acting weird after 'if' statement

75 Views Asked by At

I am doing a Pong game, following an online Python course and I have encountered a unsolvable problem with Turtle. I have checked the code several times but it appears just as it is in the course assignment but on my end the results are different.

I am making a class about the ball:

from turtle import Turtle


class Ball(Turtle):

    def __init__(self):
        super().__init__()
        self.shape('circle')
        self.color('white')
        self.shapesize(stretch_wid=1, stretch_len=1)
        self.penup()
        self.x_move = 10
        self.y_move = 10

    def move(self):
        new_x = self.xcor() + self.x_move
        new_y = self.xcor() + self.y_move
        self.goto(new_x, new_y)

    def bounce_y(self):
        self.y_move *= -1

    def bounce_3(self):
        self.x_move *= -1

And then in the main.py I am making a wall collision detection using the following:

    if ball.ycor() > 280 or ball.ycor() < -280:
        ball.bounce_y()

Technically, this should result in the ball bouncing off the top end of the screen but in reality it starts doing zig-zag movements as the ycor are changing from -10 to +30 and then -10 and +30 again, until I stop the program:

y: 240.0
y: 250.0
y: 260.0
y: 270.0
y: 280.0
y: 290.0
y: 280.0
y: 290.0
y: 320.0
y: 310.0
y: 340.0
y: 330.0
y: 360.0
y: 350.0
y: 380.0
y: 370.0
y: 400.0
y: 390.0
y: 420.0
y: 410.0
y: 440.0
y: 430.0
y: 460.0
y: 450.0

I have checked my code several times but I really have no idea where's the problem so I will appreciate any hints and ideas where to look for a mistake.

1

There are 1 best solutions below

5
Elerium115 On

Imagine for a moment that your ball somehow reaches the value 300 (which is a forbidden zone for the ball).

It will bounce and then go back 10 pixels to 290, but 290 > 280 so it will bounce again and go up to 300. It will always get stuck bouncing.

What you need to do not only check the position the ball is, but also the direction of the ball. If the ball is too high but is already descending, do not bounce it (same if it's too low but already ascending)

if ball.ycor() > 280 and ball.y_move > 0:
    ball.bounce_y()
elif ball.ycor() < -280 and ball.y_move < 0:
    ball.bounce_y()

Also instead of first moving the ball to a potentially invalid position and then bouncing it, you should probably first check if the target position is valid, and bounce it before reaching such invalid position.