I’m having a problem where the ball in my pong game doesn’t always detect when it touches a paddle, if it touches the same paddle twice in a row it just goes straight through, this happens when the opponent misses the ball, since then its respawned to go back to the winner of the point.
The game consist of a main module and a game module, the game module has a class that controlls everything related to the game, the only thing the main class has to do to make the game run is call the next_step() function, and this is where the problem lies.
Every time the next step function is run it checks for collisions between the ball and the paddle. Does anyone have an idea as to why this problem is occuring?
import pygame
import random
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
class game:
def __init__(self, window_height, window_width, ball_speed, paddle_speed):
#game constants
self.paddle_height = 70
self.paddle_width = 10
self.ball_size = 15
self.ball_speed_increase = 1.02
self.window_height = window_height
self.window_width = window_width
self.ball_speed = ball_speed
self.ball_speed = ball_speed
self.left_score = 0
self.right_score = 0
self.frames_passed = 0
self.game_done = False
#initialize game objects
self.left_paddle = paddle(0, window_height/2-self.paddle_height/2, self.paddle_width, self.paddle_height, WHITE, paddle_speed, window_height, window_width ,False)
self.right_paddle = paddle(window_width-self.paddle_width, window_height/2-self.paddle_height/2, self.paddle_width, self.paddle_height, WHITE, paddle_speed, window_height, window_width,True)
self.ball = Ball(window_width//2-(self.ball_size/2), window_height//2-(self.ball_size/2), self.ball_size, WHITE)
#moves paddles given inputs
def move_paddles(self, inputs):
if inputs[0] == 1:
self.left_paddle.move_up()
if inputs[1] == 1:
self.left_paddle.move_down()
if inputs[2] == 1:
self.right_paddle.move_up()
if inputs[3] == 1:
self.right_paddle.move_down()
#sets the ball speed and direction
def set_ball_speed(self, ball_speed, paddle_angle):
self.ball.direction[0] = ball_speed
if paddle_angle > 1: paddle_angle = 1
self.ball.direction[1] = paddle_angle * abs(ball_speed) * -1
#steps the game
def next_step(self, inputs):
#check if the ball is out of bounds
if self.ball.accurate_rect[0] > self.window_width + self.ball.size:
self.left_score += 1
self.ball.reset(self.window_height, self.window_width)
elif self.ball.accurate_rect[0] < 0:
self.right_score += 1
self.ball.reset(self.window_height, self.window_width)
#check collisions
if self.ball.rect.colliderect(self.left_paddle) and self.ball_speed < 0:
print("collision")
self.ball_speed = self.ball_speed * -self.ball_speed_increase
ball_offset = self.left_paddle.center - self.ball.center
paddle_angle = ball_offset * 7 / self.left_paddle.center
self.set_ball_speed(self.ball_speed, paddle_angle)
elif self.ball.rect.colliderect(self.right_paddle) and self.ball_speed > 0:
print("collision")
self.ball_speed = self.ball_speed * -self.ball_speed_increase
ball_offset = self.right_paddle.center - self.ball.center
paddle_angle = ball_offset * 7 / self.right_paddle.center
self.set_ball_speed(self.ball_speed, paddle_angle)
#check bounce off ceiling
if self.ball.rect.y < 0 or self.ball.rect.y + self.ball_size > self.window_height:
self.ball.direction[1] = self.ball.direction[1] * -1
#move the ball
self.ball.move()
self.move_paddles(inputs)
self.frames_passed += 1
if self.frames_passed > 60*60: return True
else: return False
#returns game data
def get_game_state(self, score=False):
if score: return self.left_score, self.right_score
return self.left_paddle, self.right_paddle, self.ball
class paddle:
def __init__(self, x, y, width, height, color, speed, window_height, window_width, right_paddle=True):
#initialize paddle
self.rect = pygame.Rect(x, y, width, height)
self.color = color
self.speed = speed
self.width = width
self.height = height
self.center = self.height // 2 + self.rect.y
self.window_height = window_height
self.window_width = window_width
self.right_paddle = right_paddle
def move_up(self):
self.rect.y -= self.speed
if self.rect.y < 0:
self.rect.y = 0
self.center = self.height // 2 + self.rect.y
def move_down(self):
self.rect.y += self.speed
if self.rect.y > self.window_height - self.height:
self.rect.y = self.window_height - self.height
self.center = self.height // 2 + self.rect.y
class Ball:
def __init__(self, x, y, size, color):
#initialize ball
self.size = size
self.rect = pygame.Rect(x, y, size, size)
self.accurate_rect = [self.rect.x, self.rect.y]
self.color = color
self.direction = [5, 0]
def move(self):
self.center = self.size // 2 + self.rect.y
self.accurate_rect[0] += self.direction[0]
self.accurate_rect[1] += self.direction[1]
self.rect.x = round(self.accurate_rect[0])
self.rect.y = round(self.accurate_rect[1])
def reset(self, window_height, window_width):
self.accurate_rect[1] = window_height // 2
self.accurate_rect[0] = window_width // 2
self.direction[0] *= -1
self.direction[1] = 0
1