100 Days of Code: The Complete Python Pro Bootcamp for 2022 - Day 22 (Build Pong The Famous Arcade Game)
Published: 2022-06-12 20:46:27

- What we're going to do

1. Setup the main screen

2. Create a paddle that responds to Key presses

3. Write a paddle class and create a second paddle

4. Write the ball class and make the ball move

5. Add the bouncing ball logic

6. How to detect collision with the paddle

7. How to detect when the ball goes out of bounds

8. Score keeping and changing the ball speed


- main.py
````python
from turtle import Screen
from paddle import Paddle
from ball import Ball
from score import Scoreboard
import time

# Screen setup
screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor("black")
screen.title("Pong")
screen.tracer(0)


# Initiate 2 x paddles(left, right) and ball
l_paddle = Paddle((-350, 0))
r_paddle = Paddle((350, 0))
ball = Ball()
score = Scoreboard()

# Screen settings
screen.listen()
screen.onkeypress(r_paddle.go_up, "Up")
screen.onkeypress(r_paddle.go_down, "Down")
screen.onkeypress(l_paddle.go_up, "a")
screen.onkeypress(l_paddle.go_down, "s")


# Game logic
game_is_on = True

while game_is_on:
    screen.update()
    time.sleep(ball.mov_speed)
    ball.move()

    # Detect collision with wall at ycor, bounce the ball off the wall
    if ball.ycor() > 280 or ball.ycor() < -280:
        ball.bounce_y()

    # Detect collision with paddle
    if ball.distance(r_paddle) < 50 and ball.xcor() > 320 or ball.distance(l_paddle) < 50 and ball.xcor() > -320:
        ball.bounce_x()

    # Detect r_paddle misses
    if ball.xcor() > 380:
        ball.reset_position()
        score.l_point()

    # Detect l_paddle misses
    if ball.xcor() < -380:
        ball.reset_position()
        score.r_point()

    # Game Over
    if score.l_score >= 3 or score.r_score >= 3:
        game_is_on = False
        score.game_over()


screen.exitonclick()

```

- paddle.py
````python
from turtle import Turtle


class Paddle(Turtle):

    def __init__(self, position):
        super().__init__()
        self.shape("square")
        self.color("white")
        self.shapesize(stretch_wid=3, stretch_len=1)
        self.penup()
        self.goto(position)

    def go_up(self):
        new_y = self.ycor() + 20
        self.penup()
        self.goto(self.xcor(), new_y)

    def go_down(self):
        new_y = self.ycor() - 20
        self.penup()
        self.goto(self.xcor(), new_y)

```

- ball.py
````python
from turtle import Turtle


class Ball(Turtle):

    def __init__(self):
        super().__init__()
        self.shape("circle")
        self.color("white")
        self.shapesize(stretch_wid=1, stretch_len=1)
        self.penup()
        self.x_mov = 10
        self.y_mov = 10
        self.mov_speed = 0.1

    def move(self):
        new_x = self.xcor() + self.x_mov
        new_y = self.ycor() + self.y_mov
        self.goto(new_x, new_y)

    def bounce_y(self):
        self.y_mov *= -1
        self.mov_speed *= 0.9

    def bounce_x(self):
        self.x_mov *= -1

    def reset_position(self):
        self.goto(0, 0)
        self.mov_speed = 0.1
        self.bounce_x()

```

- score.py
````python
from turtle import Turtle

ALIGNMENT = "center"
FONT = ("Courier", 60, "bold")


class Scoreboard(Turtle):

    def __init__(self):
        super().__init__()
        self.hideturtle()
        self.l_score = 0
        self.r_score = 0
        self.penup()
        self.color("white")
        self.update_scoreboard()

    def update_scoreboard(self):
        self.clear()
        self.goto(-75, 200)
        self.write(self.l_score, align=ALIGNMENT, font=FONT)
        self.goto(75, 200)
        self.write(self.r_score, align=ALIGNMENT, font=FONT)

    def l_point(self):
        self.l_score +=1
        self.update_scoreboard()

    def r_point(self):
        self.r_score += 1
        self.update_scoreboard()

    def game_over(self):
        self.goto(0, 0)
        self.write("Game Over", align=ALIGNMENT, font=FONT)

```