Pong Game with Paddles and a Bouncing Ball

Importing the Required Module

We begin by importing the pgzrun module to utilize Pygame Zero functionalities:


    import pgzrun

Setting Up the Window

The dimensions of the game window are established, with a width of 600 pixels and a height of 450 pixels:


    WIDTH = 600
    HEIGHT = 450

Configuring the Ball Properties

We configure the properties of the ball like its position, size, color, and velocity:


    ball = {
        'x': WIDTH // 2,
        'y': HEIGHT // 2,
        'radius': 15,
        'color': (255, 255, 255),
        'dx': 4,
        'dy': 4
    }

Configuring the Paddle Properties

Similarly, we establish the properties of the paddles including dimensions, speed, and initial positions:


    paddle_height = 80
    paddle_width = 15
    paddle_speed = 4
    left_paddle = {'x': 0 + (paddle_width // 2), 'y': HEIGHT // 2, 'dy': 0}
    right_paddle = {'x': WIDTH - (paddle_width // 2), 'y': HEIGHT // 2, 'dy': 0}

Updating Positions

Initially, the function modifies the positions of the ball and paddles:


    def update():
        ball['x'] += ball['dx']
        ball['y'] += ball['dy']
        left_paddle['y'] += left_paddle['dy']
        right_paddle['y'] += right_paddle['dy']
                

Ball Collision with Top and Bottom Walls

Checks if the ball collides with the top or bottom walls and reverses its y-direction velocity accordingly:

    
        if ball['y'] <= ball['radius'] or ball['y'] >= HEIGHT - ball['radius']:
            ball['dy'] = -ball['dy']

Ball Collision with Paddles

This part ensures the ball bounces back when colliding with a paddle by reversing its x-direction velocity:

    
        if ball['dx'] < 0 and left_paddle['y'] - paddle_height // 2 <= ball['y'] <= left_paddle['y'] + paddle_height // 2 and ball['x'] <= left_paddle['x'] + paddle_width // 2:
            ball['dx'] = -ball['dx']
        elif ball['dx'] > 0 and right_paddle['y'] - paddle_height // 2 <= ball['y'] <= right_paddle['y'] + paddle_height // 2 and ball['x'] >= right_paddle['x'] - paddle_width // 2:
            ball['dx'] = -ball['dx']

Paddle Collision with Top and Bottom

This section prevents paddles from moving outside the screen by restricting their movement within the screen height:


        for paddle in [left_paddle, right_paddle]:
            if paddle['y'] < paddle_height // 2:
                paddle['y'] = paddle_height // 2
            elif paddle['y'] > HEIGHT - paddle_height // 2:
                paddle['y'] = HEIGHT - paddle_height // 2
            

Reset Ball Position

If the ball goes beyond the screen width (x-axis), its position and velocity are reset to initial conditions:

    
        if ball['x'] < 0 or ball['x'] > WIDTH:
            ball['x'] = WIDTH // 2
            ball['y'] = HEIGHT // 2
            ball['dx'] = 4 if ball['dx'] < 0 else -4
        

The draw() Function

This function updates the screen, drawing the paddles and ball in their new positions:


    def draw():
        screen.fill((0, 0, 0))
        screen.draw.filled_circle((ball['x'], ball['y']), ball['radius'], ball['color'])
        screen.draw.filled_rect(Rect((left_paddle['x'] - paddle_width // 2, left_paddle['y'] - paddle_height // 2), (paddle_width, paddle_height)), (255, 255, 255))
        screen.draw.filled_rect(Rect((right_paddle['x'] - paddle_width // 2, right_paddle['y'] - paddle_height // 2), (paddle_width, paddle_height)), (255, 255, 255))
                

Handling Key Presses and Releases

The on_key_down() and on_key_up() functions are used to control the paddles when certain keys are pressed and released:


    def on_key_down(key):
        if key == keys.W:
            left_paddle['dy'] = -paddle_speed
        elif key == keys.S:
            left_paddle['dy'] = paddle_speed
        elif key == keys.UP:
            right_paddle['dy'] = -paddle_speed
        elif key == keys.DOWN:
            right_paddle['dy'] = paddle_speed
                
    def on_key_up(key):
        if key == keys.W or key == keys.S:
            left_paddle['dy'] = 0
        elif key == keys.UP or key == keys.DOWN:
            right_paddle['dy'] = 0
                

Executing the Game

Lastly, pgzrun.go() perpetually runs the game, repeatedly invoking update() and draw() functions:


    pgzrun.go()
    

Copyright © KX Technology Group, LLC. All Rights Reserved.