I'm trying to code a pong game on Python with Pygame. Weirdly, the game works good, the ball bounces off on edges, respawns using space, the paddles move (up/down arrow and i/k keys) without leaving the screen. Most of the time the ball collides with paddles but some other times the ball acts weirdly or teleports.
I thought the problem might with the collision logic. So that's what I'm sharing, if you want more there's the link below.
P1 and P2 represent the paddles. Basically I check if x is near the paddle and then check if y is in the paddle range (from topPaddleY to bottomPaddleY) For more code, I'm sharing it with codeskulptor3. https://py3.codeskulptor.org/#user305_Voqctw5Vzh_0.py
class Ball:
def __init__(self, radius, center, color):
self.radius = radius
self.initial_attributes = center
self.center = list(center)
self.color = color
self.vel = [random.choice(VELOCITIES), random.choice(VELOCITIES)]
def draw(self):
pygame.draw.circle(screen, self.color, tuple(self.center), self.radius )
def update(self, p1, p2):
x = self.center[0]
y = self.center[1]
y_adjusted = (y+self.radius, y-self.radius)
if y_adjusted[0] >= HEIGHT or y_adjusted[1] <= 0:
self.vel[1] = -self.vel[1]
if x <= 28 or x >= WIDTH - 28:
p1_range = [p1.pos[1], p1.pos[1] + 100]
if p1_range[0] <= y <= p1_range[1]:
self.vel[0] = (-self.vel[0])
p2_range = [p2.pos[1], p2.pos[1] + 100]
if p2_range[0] <= y <= p2_range[1]:
self.vel[0] = (-self.vel[0])
def move(self, p1, p2):
self.center[0] = self.center[0] + self.vel[0]
self.center[1] = self.center[1] + self.vel[1]
self.update(p1, p2)
keys = pygame.key.get_pressed()
if keys[pygame.K_SPACE]:
self.spawn()
def spawn(self):
self.center = list(self.initial_attributes)
self.vel = [random.choice(VELOCITIES), random.choice(VELOCITIES)]
Edit : I was able to fix it by using as suggested the y_adjusted + adding a print statement to check the position of the ball during the collision. It appeared that velocity changed more than once during the collision So i added a flag for reflection. It seems to be rolling good now. Thanks SO.
def update(self, p1, p2):
x = self.center[0]
y = self.center[1]
y_adjusted = (y+self.radius, y-self.radius)
reflected = False
if y_adjusted[0] >= HEIGHT or y_adjusted[1] <= 0:
self.vel[1] = -self.vel[1]
if x <= 28 or x >= WIDTH - 28:
p1_range = [p1.pos[1], p1.pos[1] + 100]
if ((p1_range[0] <= y_adjusted[0] <= p1_range[1]) or (p1_range[0] <= y_adjusted[1] <= p1_range[1])) and (not(reflected)):
self.vel[0] = (-self.vel[0])
reflected = True
p2_range = [p2.pos[1], p2.pos[1] + 100]
if ((p2_range[0] <= y_adjusted[0] <= p2_range[1]) or (p2_range[0] <= y_adjusted[1] <= p2_range[1])) and (not(reflected)):
self.vel[0] = (-self.vel[0])
reflected = True
else :
reflected = False
if p2_range[0] <= y <= p2_range[1]:What's the reason for not usingy_adjustedas you did above? - TheLazyScripter