1

I have made a ball sprite which is supposed to bounce around the screen. It works for the bottom and right side of the screen, but not the left or the top. (Note that the x, y is counted from the top left corner, i.e x is 0 at the left side and y is 0 at the top). Once the ball touches the top or the left, it just goes into it and gets stuck there. Like this:

gif shows ball getting stuck at top left corner

Heres the edge detection code:

    def edgedetect(self):

        if self.position.x + self.radius >= width or self.position.x <= self.radius:
            self.velocity.x *= -0.9
            self.velocity.y *= 0.99

        if self.position.y + self.radius >= height or self.position.y <= self.radius:
            self.velocity.y *= -0.9
            self.velocity.x *= 0.99

(x,y is counted from the top and left respectively)

self.position: a vector which holds the coords of the center of the ball

self.velocity: a vector which holds the velocity of the ball, which is added onto the position every frame

Is there a better way to do this ?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • The problem is probably elsewhere in your code. As a basic debugging, try to print the coordinates and speed in order to see what's going on. – Thierry Lathuille Aug 15 '21 at 11:22
  • 2
    In the if-statement, reset the position to a valid position. So if it goes past the left edge, set `self.position.x = self.radius + 0.1`. That way, you won't be in a situation where the ball goes through the wall just because you were moving too fast. I'm guessing that's your problem because you'll be switching the velocity back and fourth every frame since the if-statement will be executed every frame. – Ted Klein Bergman Aug 15 '21 at 11:32

1 Answers1

0

Your edgedetect should switch direction only once, and do nothing until a ball returns to allowed area:

    def __init__(self, ...):
        ...
        self.is_x_out_of_bounds = False
        self.is_y_out_of_bounds = False

    ...
    
    def edgedetect(self):
        if self.position.x + self.radius >= width or self.position.x < self.radius:
            if not self.is_x_out_of_bounds:
                self.is_x_out_of_bounds = True
                self.velocity.x *= -0.9
                self.velocity.y *= 0.99
        else:
            self.is_x_out_of_bounds = False

        if self.position.y + self.radius >= height or self.position.y < self.radius:
            if not self.is_y_out_of_bounds:
                self.is_y_out_of_bounds = True
                self.velocity.y *= -0.9
                self.velocity.x *= 0.99
        else:
            self.is_y_out_of_bounds = False

beside of that, better use < instead of <= in left and top boundaries collision checks, as long as 0 is legit position for point on a screen.

madbird
  • 1,326
  • 7
  • 11