pythonpygamepong

win variable not being set to False


I am making a pong game with pygame. The check_win() function checks if one side has won and for some reason, it the point counter keeps going up on the right side when detected, but not on the left side. So when it detects the ball hit the left wall, it works as intended, but when it hits the right side, it keeps incrementing the point.

here the code

import pygame

pygame.init()

class Pad:
    def __init__(self, x, win, score_x):
        self.win = win
        self.x = x
        self.y = 250
        self.speed = 5
        self.score = 0
        self.score_x = score_x
        self.color = (255, 255, 255)

        self.font = pygame.font.Font("font.ttf", 25)

        self.base = pygame.Rect(0, 0, 30, 100)
        self.base.center = (self.x, self.y)

        self.collide_base = pygame.Rect(0, 0, 10, self.base.height)

    def render(self, type_):
        if type_ == 0:
            self.collide_base.right = self.base.right
        if type_ == 1:
            self.collide_base.left = self.base.left

        self.collide_base.y = self.base.y
        pygame.draw.rect(self.win, self.color, self.base)

    def move(self, keys, type_):
        if type_ == 0:
            if keys[pygame.K_w]:
                self.base.centery -= self.speed

            if keys[pygame.K_s]:
                self.base.centery += self.speed

        elif type_ == 1:
            if keys[pygame.K_UP]:
                self.base.centery -= self.speed

            if keys[pygame.K_DOWN]:
                self.base.centery += self.speed

    def collide_edge(self):
        if self.base.bottom >= self.win.get_height():
            self.base.y -= self.speed

        if self.base.top <= 0:
            self.base.y += self.speed

    def draw_score(self):
        score = self.font.render(str(self.score), False, self.color)
        self.win.blit(score, (self.score_x, self.win.get_height() - (self.win.get_height() - 20)))

class Ball:
    def __init__(self, win):
        self.win = win
        self.color = (255, 255, 255)
        self.leftWin = False
        self.rightWin = False

        self.speedx = 5
        self.speedy = 5
        self.x = self.win.get_width() / 2
        self.y = self.win.get_height() / 2

        self.base = pygame.Rect(0, 0, 20, 20)
        self.base.center = (self.x, self.y)

    def render(self):
        self.base.center = (self.x, self.y)
        pygame.draw.ellipse(self.win, self.color, self.base)

    def move(self):
        if self.base.bottom >= self.win.get_height():
            self.speedy *= -1

        if self.base.right >= self.win.get_width():
            self.rightWin = True

        if self.base.top <= 0:
            self.speedy *= -1

        if self.base.left <= 0:
            self.leftWin = True

        self.x += self.speedx
        self.y += self.speedy


class Game:
    def __init__(self):
        self.width = 750
        self.height = 500
        self.running = True
        self.color = (0, 0, 0)
        self.fps = 60

        self.win = pygame.display.set_mode((self.width, self.height), pygame.RESIZABLE)
        self.clock = pygame.time.Clock()
        self.pad1 = Pad(50, self.win, self.width / 2 + 25)
        self.pad2 = Pad(700, self.win, self.width / 2 - 40)
        self.ball = Ball(self.win)

        self.line = []

    def draw_line(self):
        for x in range(20):
            if x % 2 == 0:
                rect = pygame.Rect(0, 0, 20, 40)
                rect.center = (self.width / 2, x * 40)

                self.line.append(rect)

        for rect in self.line:
            pygame.draw.rect(self.win, (255, 255, 255), rect)

    def check_pad(self):
        if self.ball.base.colliderect(self.pad1.base):
            self.ball.x += 10
            self.ball.speedx *= -1

        if self.ball.base.colliderect(self.pad2.base):
            self.ball.x -= 10
            self.ball.speedx *= -1

    def check_win(self):
        if self.ball.leftWin:
            self.ball.base.center = (self.width / 2, self.height / 2)

            self.ball.leftWin = False

            self.ball.speedx = 5
            self.ball.speedy = 5

            self.pad1.score += 1

        if self.ball.rightWin:
            self.ball.base.center = (self.width / 2, self.height / 2)

            self.ball.rightWin = False

            self.ball.speedx = 5
            self.ball.speedy = 5

            self.pad2.score += 1


    def run(self):
        while self.running:
            self.clock.tick(self.fps)
            self.win.fill(self.color)

            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    self.running = False

            keys = pygame.key.get_pressed()

            self.draw_line()
            self.check_pad()
            self.check_win()

            self.ball.render()
            self.ball.move()

            self.pad1.render(0)
            self.pad1.move(keys, 0)
            self.pad1.collide_edge()
            self.pad1.draw_score()

            self.pad2.render(1)
            self.pad2.move(keys, 1)
            self.pad2.collide_edge()
            self.pad2.draw_score()

            pygame.display.update()

        pygame.quit()

if __name__ == '__main__':
    Game().run()

Solution

  • You have forgotten to update self.ball.x and self.ball.y. Note, self.base.center is set from self.x, self.y in the function render.

    class Game:
        # [...]
    
        def check_win(self):
            if self.ball.leftWin:
                self.ball.base.center = (self.width / 2, self.height / 2)
                self.ball.x, self.ball.y = self.ball.base.center           # <---
    
                self.ball.leftWin = False
                self.ball.speedx = 5
                self.ball.speedy = 5
                self.pad1.score += 1
    
            if self.ball.rightWin:
                self.ball.base.center = (self.width / 2, self.height / 2)
                self.ball.x, self.ball.y = self.ball.base.center             # <---
    
                self.ball.rightWin = False
                self.ball.speedx = 5
                self.ball.speedy = 5
                self.pad2.score += 1