Search code examples
pythonpygameupdatingpong

Score Not Updating Pong Pygame


I'm not sure why the score isn't updating. When either player scores the debugger prints 0's. Here are my score variables.

player_score = 0
opponent_score = 0
basic_font = pygame.font.Font('freesansbold.ttf', 32)

And the variables for rendering the score:

player_text = basic_font.render(f'{player_score}', False, light_grey)
screen.blit(player_text, (660, 470))

opponent_text = basic_font.render(f'{opponent_score}', False, light_grey)
screen.blit(opponent_text, (600, 470))

And my update method.

    def update(self, left_paddle, right_paddle, player_score, opponent_score):
    self.rect.x += self.vx
    self.rect.y += self.vy

    if self.rect.top <= 0 or self.rect.bottom >= screen_height:
        self.vy *= -1

    if self.rect.left <= 0:
        self.ball_start()
        player_score += 1

    if self.rect.right >= screen_width:
        self.ball_start()
        opponent_score += 1

    if self.rect.colliderect(left_paddle) or self.rect.colliderect(right_paddle):
        self.vx *= -1

def ball_start(self):
    self.rect.center = (screen_width / 2, screen_height / 2)
    self.vy *= random.choice((1, -1))
    self.vx *= random.choice((1, -1))

And then i call the update method:

ball.update(left_paddle, right_paddle, player_score, opponent_score)

Here's the code for the project. Your help would be greatly appreciated.

import logging
import pygame, sys
from inputs import handle_input
import random


class Paddle:
    def __init__(self):
        self.rect = pygame.Rect(10, screen_height / 2 - 70, 10, 140)

        self.speed = 10

    def draw(self, screen):
        pygame.draw.rect(screen, light_grey, self.rect)

    def move_up(self):
        self.rect.y -= self.speed
        self._keep_in_bounds()

    def move_down(self):
        self.rect.y += self.speed
        self._keep_in_bounds()

    def _keep_in_bounds(self):
        if self.rect.top <= 0:
            self.rect.top = 0

        if self.rect.bottom >= screen_height:
            self.rect.bottom = screen_height


class Ball:
    def __init__(self, x, y, width, height):
        self.rect = pygame.Rect(x, y, width, height)
        self.speed = 7
        self.vx = self.speed * random.choice((1, -1))
        self.vy = self.speed * random.choice((1, -1))

    def draw(self, screen):
        pygame.draw.ellipse(screen, light_grey, self.rect)

    def update(self, left_paddle, right_paddle, player_score, opponent_score):

        self.rect.x += self.vx
        self.rect.y += self.vy

        if self.rect.top <= 0 or self.rect.bottom >= screen_height:
            self.vy *= -1

        if self.rect.left <= 0:
            self.ball_start()
            player_score += 1

        if self.rect.right >= screen_width:
            self.ball_start()
            opponent_score += 1

        if self.rect.colliderect(left_paddle) or self.rect.colliderect(right_paddle):
            self.vx *= -1

    def ball_start(self):
        self.rect.center = (screen_width / 2, screen_height / 2)
        # print(self.rect.center)
        self.vy *= random.choice((1, -1))
        self.vx *= random.choice((1, -1))


# General setup
pygame.init()
clock = pygame.time.Clock()

# Main Window
screen_width = 1280
screen_height = 800
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption('Pong')

# Colors
light_grey = (200, 200, 200)
bg_color = pygame.Color('grey12')

# Game Rectangles
ball = Ball(screen_width / 2 - 15, screen_height / 2 - 15, 30, 30)
left_paddle = Paddle()
right_paddle = Paddle()
right_paddle.rect.x = screen_width - right_paddle.rect.width

player_score = 0
opponent_score = 0
basic_font = pygame.font.Font('freesansbold.ttf', 32)

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    # Game logic
    handle_input(left_paddle, right_paddle)
    screen.fill(bg_color)
    pygame.draw.aaline(screen, light_grey, (screen_width / 2, 0), (screen_width / 2, screen_height))
    ball.draw(screen)
    left_paddle.draw(screen)
    right_paddle.draw(screen)
    ball.update(left_paddle, right_paddle, player_score, opponent_score)

    player_text = basic_font.render(f'{player_score}', False, light_grey)
    screen.blit(player_text, (660, 470))

    opponent_text = basic_font.render(f'{opponent_score}', False, light_grey)
    screen.blit(opponent_text, (600, 470))

    pygame.display.flip()
    clock.tick(60)

Solution

  • Your updates are not getting reflected in the global variables because you are simply not updating them. You are updating a local copy of them, which you got from passing them to the Ball.update function.

    Try this:

    def update(self, left_paddle, right_paddle):
        global player_score, opponent_score
    
        ...
    
        if self.rect.left <= 0:
            self.ball_start()
            player_score += 1
    
        if self.rect.right >= screen_width:
            self.ball_start()
            opponent_score += 1
    
        ...
        # function ends here
    

    I think the best would be to create a Player class and keep track of scores there only and, pass instances of this Player class to the update function. Then, later retrieve the scores form these instances.