# 12.1. Pong - The Simplest Game to Implement

I recently got the idea to recreate the classic arcade game of Pong. Pong is a relatively simple game with little programming required to get it up and running. In this article, we will see how the code works.

As usual, we will start with the `setup()`. This is available in `Pong.pde`, the project's main file.

```java
void setup() {
    size(1000, 600);
    frameRate(60);

    PFont font = loadFont("font.vlw");
    textFont(font);

    rectMode(CENTER);

    player_one = new Paddle("1", 100, height / 2, 0, height, 10, 100);
    player_two = new Paddle("2", width - 100, height / 2, 0, height, 10, 100);

    ball = new Ball(width / 2, height / 2, 10, 10, width, height);
    ball.reset();
}
```

This is pretty standard: Set the canvas size, frame rate, load fonts, set the rectangle mode and set up the objects for the players and ball. I have discussed loading the fonts in the previous article, so I will not go through it here. You can also refer to the [GitHub repo](https://github.com/asankaSovis/Pong) for the instructions.

The font I chose was `Bitwise Font` by *Digital Graphics Labs*. You can find it at [www.fontspace.com](https://www.fontspace.com/bitwise-font-f5077).

![Bitwise Font](https://cdn.hashnode.com/uploads/covers/61a2243af0cb2e37690c63e1/4e19c17e-8dcb-43f4-86ac-a7c2938e91e7.png align="center")

The `draw()` function is also quite simple.

```java
void draw() {
    background(0);
    backgroundDraw();

    render();

    if (!pause) {
        update();
    }
}
```

We first draw a black background, draw the background items and then render the dynamic items. If we're not on pause, we also update the physics.

The `keyPressed()` function is also quite simple.

```java
void keyPressed() {
    if (key == 'w') { player_one.up(); }
    if (key == 's') { player_one.dn(); }

    if (key == 'p') { player_two.up(); }
    if (key == 'l') { player_two.dn(); }

    if (key == 'r') { reset(); }

    if (key == ' ') {
        if ((player_one.score(0) > over) || (player_two.score(0) > over)) {
            reset();
        }

        pause = !pause;
    }
}
```

Pressing the keys `w` and `s` will move player one up and down. `p` and `l` for player two. `r` will reset the game, and the space will reset the game if either player has completed the scores, and pause either way. `mousePressed()` is also the same as pressing the space.

```java
void mousePressed() {
    if ((player_one.score(0) > over) || (player_two.score(0) > over)) {
        reset();
    }

    pause = !pause;
}
```

Background draw is long, but it pretty much does some basic shape drawing as well.

```java
void backgroundDraw() {
    fill(255);

    rect(width / 2, height / 2, 5, height);

    textAlign(CENTER, CENTER);
    textSize(32);

    text(player_one.score(0), 50, 100);
    text(player_two.score(0), width - 50, 100);

    if (pause) {
        if ((player_one.score(0) > over) || (player_two.score(0) > over)) {
            String p = "1";
            if (player_two.score(0) > over) {
                p = "2";
            }

            text("GAME   OVER\n   PLAYER " + p + "      HAS  WON\n   CLICK OR PRESS   SPACE TO START", width / 2, 400);
        } else {
            text("PO  NG\n   CLICK OR PRESS   SPACE TO START", width / 2, 400);
        }
    }
}
```

The colour we use for drawing is white. We first draw a divider in the centre of the screen. Then we draw the scores of each player. If paused, we also draw some text on the screen. If either of the player has exceeded the winning score, we display the winner; if not, we show instructions to play the game.

`reset()` and `render()` also perform similar functions.

```java
void reset() {
    ball.reset();

    player_one.reset();
    player_two.reset();
}

void render() {
    ball.render();

    player_one.render();
    player_two.render();
}
```

We either reset or render the two players and ball.

`update()` function handles all the physics.

```java
void update() {
    if (frameCount % 2 == 0) {
        int upd = ball.update();

        if (upd > 0) {
            if (upd == 1) { player_one.score(1); }
            if (upd == 2) { player_two.score(1); }

            if ((player_one.score(0) > over) || (player_two.score(0) > over)) {
                pause = true;
            }

            ball.reset();
        }
    }
}
```

Here, for every two frames, we perform a physics update. First, the ball is updated. It will return if either of the players scored. 0 means no score, and either 1 or 2 represents the player who scored. So, if we have a return greater than 0, we check if it's 1 or 2 and increase the score of the respective player. We also check if any of the players have reached the winning score and pause if so. We also reset the ball.

Now, we will move on to the next file: `Game.pde`. This has all the classes related to the ball and player.

The first one we will look at is the player: the `Paddle` class.

```java
public class Paddle {
    private String id;

    private int start_x, start_y;

    private int x, y;

    private int width, height;

    private int up_x, dn_x;

    private int score = 0;

    private int SPEED = 10;
    
    public Paddle(String id, int x, int y, int up_x, int dn_x, int width, int height) {
        this.id = id;
        this.start_x = x; this.start_y = y;
        this.x = x; this.y = y;
        this.up_x = up_x; this.dn_x = dn_x;
        this.width = width; this.height = height;
    }

    public String id();
    
    public void render();

    public void reset();

    public void up();

    public void dn();

    public int score(int sc);
}
```

We have a few private variables that are quite simple. `id` holds a unique identifier for the player. `start_x` and `start_y` represent the initial positions of the paddle. `x` and `y` relate to where the paddle is now. `width` and `height` are the width and height of the paddle. `up_` and `dn_x` are the limits when moving the paddle up and down. `score` is the score of the player, and `SPEED` is the speed of the paddle. The constructor sets these up.

`id()` returns the ID of the player.

```java
public String id() {
    return id;
}
```

`render()` renders the paddle.

```java
public void render() {
    fill(255);
    rect(this.x, this.y, this.width, this.height);
}
```

`reset()` resets the paddle to its initial position.

```java
public void reset() {
    this.x = this.start_x; this.y = this.start_y;
    score = 0;
}
```

`up()` and `dn()` move the paddle up or down by the `SPEED`.

```java
public void up() {
    if (this.y > up_x) {
        this.y -= SPEED;
    }
}

public void dn() {
    if (this.y < dn_x) {
        this.y += SPEED;
    }
}
```

`score()` will increase the score and return the current score.

```java
public int score(int sc) {
    this.score += sc;

    return this.score;
}
```

The other class we have is the `Ball` class. This class will be used to create the ball object that will be rendered on the screen.

```java
public class Ball {
    private int start_x, start_y;
    private int x, y;

    private int width, height;

    private int speed_x, speed_y;

    private int window_w, window_h;

    private int hits = 0;

    public Ball(int x, int y, int width, int height, int window_w, int window_h) {
        this.start_x = x; this.start_y = y;
        this.x = x; this.y = y;
        this.width = width; this.height = height;
        this.window_w = window_w; this.window_h = window_h;

        this.speed_x = 2 - (4 * round(random(0, 1))); this.speed_y = 2 - (4 * round(random(0, 1)));
    }

    public void reset();

    public void render();

    public int update();
}
```

The `start_x` and `start_y` variables hold the initial start position of the ball. `x` and `y` will hold the current position. `width` and `height` determine the size of the ball. `speed_x` and `speed_y` hold the current speed of the ball. `window_w` and `window_h` hold the total width and height of the screen. `hits` hold the number of hits the ball has with the paddles. The initialiser function handles setting up these variables. It also sets the speed to either direction randomly to create a sense of randomness when passing the ball.

The `reset()` function is also similar to the paddle. It just resets the position of the ball.

```java
public void reset() {
    this.x = start_x; this.y = start_y;
}
```

`render()` is also the same. It just resets the ball to the initial position.

```java
public void render() {
    fill(255);
    rect(this.x, this.y, this.width, this.height);
}
```

The `update()` function performs the physics-related tasks.

```java
public int update() {
    this.x += this.speed_x; this.y += this.speed_y;

    if ((this.y <= this.height / 2) || (this.y >= this.window_h - (this.height / 2))) {
        this.speed_y = -(this.speed_y);
    }

    if (((this.x <= player_one.x) && (this.y >= (player_one.y - (player_one.height / 2))) && (this.y <= (player_one.y + (player_one.height / 2))))
    ||  ((this.x >= player_two.x) && (this.y >= (player_two.y - (player_two.height / 2))) && (this.y <= (player_two.y + (player_two.height / 2))))) {
        int speed_offset = 0;
        int speed_max = 0;

        if (this.x <= player_one.x) {
            speed_offset = this.y - player_one.y;
            speed_max = player_one.height / 2;
        } else {
            speed_offset = this.y - player_two.y;
            speed_max = player_two.height / 2;
        }

        this.speed_y = speed_offset * 5 / speed_max;
        this.speed_x = -(this.speed_x);
        hits++;

        if (hits % 4 == 0) {
            this.speed_x += (this.speed_x / abs(this.speed_x));

            if (this.speed_y == 0) {
                this.speed_y = 1 - (2 * round(random(0, 1)));
            }
        }
    } else {
        if (this.x < player_one.x) {
            return 2;
        } else if (this.x > player_two.x) {
            return 1;
        }
    }

    return 0;
}
```

The first thing this task does is move the ball at the speed. If the ball has reached the top or bottom of the screen, the speed in the y-axis is flipped to *simulate* a bounce. Next, it will check if the ball reached each of the paddle's x positions. If so, we check if we reached away from the paddle's surface. If so, we return the opposite paddle to which it reached the end to indicate a score for the opposing player. If not, we check in which region of the paddle we reached, and we update the y speed accordingly.

For example, if the ball reached the end of the paddle, the angle at which it reflects will be higher, and if it's in the middle, the ball will directly reflect. We will also oppose the x speed while also increasing the hit count. The reason why we keep track of the hits is that the classic arcade game used to increase the speed with every four hits. Here, we're doing the same thing.

This creates the classic arcade Pong game with almost similar mechanics.

![Pong](https://cdn.hashnode.com/uploads/covers/61a2243af0cb2e37690c63e1/4f4ced50-e1e1-4497-b7ec-aec69563d346.gif align="center")

The reason why I wanted to create this is that I have another idea I want to pursue with this project. I will post a follow-up article to this with the other ideas I have. Till then, enjoy... 👋

External Links:

*   GitHub Repository with the Processing Code: [Github Repository](https://github.com/asankaSovis/Pong)
    
*   Wikipedia article on Pong: [Pong](https://en.wikipedia.org/wiki/Pong)
