JS BrainGamer Pong

BrainGamer Pong

Pong was one of the first video games ever created back in 1972. We’ll build the game step-by-step and use the BrainGamer for its ANALOG Rocker & DIGITAL Buttons to control the paddles.

Prerequisites

You must have a basic understanding of coding and read the BrainGamer Intro and have completed the Drawing lesson.


Creating the players

We’ll make this game so 2 people can play, one player will use the Rocker Switch and the other player can use the Buttons on the BrainGamer. We’ll use the DrawFillRect() function to make both players. Since the paddles only move up and down, we’ll create 1 variable for each player to track this position. Place the DrawFillRect() functions inside a while loop so we can check the position every time the program loops. Let’s also Clear() the screen at the top of the while loop and Show() the screen at the bottom.

var player1Pos = 30;
var player2Pos = 30;

while (true){
    await BrainPad.Display.Clear(0);

    await BrainPad.Display.DrawFillRect(1, 10, player1Pos, 2, 10);
    await BrainPad.Display.DrawFillRect(1, 120, player2Pos, 2, 10);

    await BrainPad.Display.Show();
    await BrainPad.System.Wait(10);
}

Creating the Net

Let’s create the playing field. To start we’ll need to create a net. We can do this by using the DrawLine() function inside of a loop. We’ll also change the value of the net by adding 5 to it. This creates spaces in the net so it looks more like the original game. Add this code just below where we create our players:

var player1Pos = 30;
var player2Pos = 30;

while (true){
    await BrainPad.Display.Clear(0);

    await BrainPad.Display.DrawFillRect(1, 10, player1Pos, 2, 10);
    await BrainPad.Display.DrawFillRect(1, 120, player2Pos, 2, 10);

var net = 0;
    while (net < 64){
        await BrainPad.Display.DrawLine(1,64, net, 64, net + 5);
        net = net + 10;
    }
    await BrainPad.Display.Show();
    await BrainPad.System.Wait(10);
}

Moving the players Analog vs Digital

Let’s start by moving the 2nd player first. We’ll use the DIGITAL buttons on the BrainGamer for this. Place this code just about where we created the player2 using DrawFillRect(). Let’s also add code to keep the paddle on the screen.

Moving player2 Digital Buttons

var Gamer = new BrainGamer(BrainPad); 

//BrainGamer Driver 

//Player Two
if (await Gamer.ButtonUp()) player2Pos = player2Pos - 4;
if (await Gamer.ButtonDown()) player2Pos = player2Pos + 4;

//Player Two Stay on Screen
if (player2Pos < 5) player2Pos = 5;
if (player2Pos > 50) player2Pos = 50;

await BrainPad.Display.DrawFillRect(1, 120, player2Pos, 2, 10);

Moving player1 Analog Rocker

To move Player 1 we’ll use the ANALOG Rocker switch on the BrainGamer.

var Gamer = new BrainGamer(BrainPad); 

//BrainGamer Driver 

//Player One
 
if (await Gamer.RockerY() < 40) player1Pos = player1Pos - 4;
if (await Gamer.RockerY() > 60) player1Pos = player1Pos + 4;

//Player One Stay on Screen
if (player1Pos < 5) player1Pos = 5;
if (player1Pos > 50) player1Pos = 50;

await BrainPad.Display.DrawFillRect(1, 10, player1Pos, 2, 10);

When we play our game, it will be DIGITAL (buttons) vs ANALOG (rocker). Which do you like better? If you’d like to know more about Digital or Analog, check out their respective lessons.

Here is the complete code we have created so far.

import { SerialUSB } from './serialusb.js';
import * as due from './duelink.js';

let BrainPad = new due.DUELinkController(new SerialUSB());
await BrainPad.Connect();

///BrainGaner Driver

var Gamer = new BrainGamer(BrainPad);

var player1Pos = 30;
var player2Pos = 30;

while (true)
{
    await BrainPad.Display.Clear(0);

    //Player One
    if (await Gamer.RockerY() < 40) player1Pos = player1Pos - 4;
    if (await Gamer.RockerY() > 60) player1Pos = player1Pos + 4;

    //Player One Stay on Screen
    if (player1Pos < 5) player1Pos = 5;
    if (player1Pos > 50) player1Pos = 50;

    await BrainPad.Display.DrawFillRect(1, 10, player1Pos, 2, 10);

    //Player Two
    if (await Gamer.ButtonUp()) player2Pos = player2Pos - 4;
    if (await Gamer.ButtonDown()) player2Pos = player2Pos + 4;

    //Player Two Stay on Screen
    if (player2Pos < 5) player2Pos = 5;
    if (player2Pos > 50) player2Pos = 50;

    await BrainPad.Display.DrawFillRect(1, 120, player2Pos, 2, 10);

    var net = 0;

    while (net < 64){
        await BrainPad.Display.DrawLine(1, 64, net, 64, net + 5);
        net = net + 10;
    }

    await BrainPad.Display.Show();
    await BrainPad.System.Wait(10);
}

Adding a ball

We’ve got our players moving and we created a net. We can’t play without a ball, so let’s add that now. First, we need to create variables to keep track of the coordinates and speed of the ball. Add the following variables just below our player1Pos and player2Pos variables:

var player1Pos = 30;
var player2Pos = 30;

var ballPosX = 15;
var ballPosY = 15;
var offsetX = 2;
var offsetY = 2;

Now that we’ve created the variables to track our ball, we can add some code to move it and draw it. Add the following inside our while loop just below the Clear() function at the top of the while loop. Use DrawCircle() to create our ball.

await BrainPad.Display.Clear(0);

//Move Ball
ballPosX = ballPosX + offsetX;
ballPosY = ballPosY + offsetY;

//Draw Ball
await BrainPad.Display.DrawCircle(1,ballPosX, ballPosY, 3);

Bouncing off the Walls

Our ball moves, except it moves right off the screen! We need to add an if-statement to detect when the ball hits a wall so that it will bounce off.

await BrainPad.Display.Clear(0);

//Move Ball
ballPosX = ballPosX + offsetX;
ballPosY = ballPosY + offsetY;

//Bounce off Walls
if (ballPosY < 5 || ballPosY > 55) {
  offsetY = offsetY * -1;
}

//Draw Ball
await BrainPad.Display.DrawCircle(1, ballPosX, ballPosY, 3);

Collision Detection

Now our ball bounces off the walls. Next, we must add some code to detect when the ball hits a player’s paddle. Using an if-statement, let’s detect the player2 side first. We only want to check when the ball is near the paddle. So we create an if-statement to check ballPosX position, then we’ll use another if- statement inside that to see if the ball hits the player2 paddle.

Let’s also add an else condition to our second if-statement to do something if the ball is missed. Remember that the comments added here will not interfere with the code.

//Check Ball Collision with Player 2
 if (ballPosX > 117){
     if (ballPosY >= player2Pos - 1 && ballPosY <= player2Pos + 12){
         offsetX = offsetX * -1;
         //Add code here when player hits ball
     }
     else{
         //Add code here when player misses
     }
 }

Before we add what happens when we miss the ball, let’s add the code to detect hitting the player1 paddle just below the player2 code we just created. Let’s also add:

//Check Ball Collision with Player 1
if (ballPosX < 12){    
    if (ballPosY >= player1Pos - 1 && ballPosY <= player1Pos + 12){
        offsetX = offsetX * -1;
        //Add code here when player hits ball
    }
    else{
        //Add code here when player misses
    }
}

Now that we have the basic functionality we can add scoring to the game. We’ll come back and increase the score based on which player misses the ball, but first let’s create those variables. Place the following with the other variables near the top of the code that we created earlier.

var player1Score = 0;
var player2Score = 0;

We have the variables for a score, now let’s show them on the screen. Add Text() function code just above the Show() function at the bottom of our while loop.

await BrainPad.Display.Clear(0);
await BrainPad.Display.DrawText(player1Score.toString(), 1, 50, 5);    
await BrainPad.Display.DrawText(player2Score.toString(), 1, 70 5);

Let’s increase the score of a player when the other player misses. We’ll do this inside the else condition in the if-statement we created to detect a collision, where we placed our Add Code comments. Let’s also add a sound using Beep() so we know when a player scores, and BrainGamer.Vibrator() when they miss.

//Check Collision with Player 2
 if (ballPosX > 118) {
     if (ballPosY >= player2Pos - 1 && ballPosY <= player2Pos + 12) {
         //Add code here when player hits ball
         offsetX = offsetX * -1;
         await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
    } else {
       //Add code here when player misses ball
        player1Score = player1Score + 1;
        await Gamer.Vibrator(true);
        await BrainPad.System.Wait(100);
        await Gamer.Vibrator(false);
        ballPosX = 15;
    }
}
//Check Collision with Player 1
if (ballPosX < 12) {
    if (ballPosY >= player1Pos - 1 && ballPosY <= player1Pos + 12) {
        //Add code here when player hits ball
        offsetX = offsetX * -1;
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
    }
    else {
        //Add code here when player misses ball
        player2Score = player2Score + 1;
        await Gamer.Vibrator(true);
        await BrainPad.System.Wait(100);
        await Gamer.Vibrator(false);
        ballPosX = 115;
        }
    }   
}

Winning the Game

Now let’s add some code to find a winner. If any player reaches 5, they win. We’ll create a variable called winner and set it to true once someone has won the game. Then we’ll use that variable to tell us when to play a sound. Add this code just above our Show() and Wait() functions at the bottom of the while loop.

if (player1Score == 5) {
        await BrainPad.Display.Clear(0);
        await BrainPad.Display.DrawTextScale("Player 1", 1, 5, 0, 2, 2);
        await BrainPad.Display.DrawTextScale("WINS!", 1, 25, 20, 2, 2);
        await BrainPad.Display.Show();
        await BrainPad.System.Wait(2000);
        winner = true;
    }

    if (player2Score == 5) {
        await BrainPad.Display.Clear(0);
        await BrainPad.Display.DrawTextScale("Player 2", 1, 5, 0, 2, 2);
        await BrainPad.Display.DrawTextScale("WINS!", 1, 25, 20, 2, 2);
        await BrainPad.Display.Show();
        await BrainPad.System.Wait(2000);
        winner = true;
    }

Finally, let’s use the foundWinner variable to tell us when to play a victory tune. We can add this at the very bottom of the while loop.

 if (winner == 1) {
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 200, 100);
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
        await BrainPad.System.Wait(2000);

        //Reset the game
        player1Pos = 30;
        player2Pos = 30;
        player1Score = 0;
        player2Score = 0;
        ballPosX = 15;
        ballPosY = 10;
        offsetX = 2;
        offsetY = 2;
        winner = 0;
    }

Final Results

Congratulations, you’ve coded Pong…the classic first video game ever created!

import { SerialUSB } from './serialusb.js';
import * as due from './duelink.js';

let BrainPad = new due.DUELinkController(new SerialUSB());
await BrainPad.Connect();


class BrainGamer {
    constructor(brainpad) {
        this.BrainPad = brainpad;
    }

    RockerX() {
        var x = this.BrainPad.Analog.Read(4);
        return x;
    }

    RockerY() {
        var y = this.BrainPad.Analog.Read(3);
        return y;
    }

    async Vibrator(enable) {
        await this.BrainPad.Digital.Write(8, !enable);
    }

    async ButtonUp() {
        return !await this.BrainPad.Digital.Read(14, this.BrainPad.Pin.PullUp);
    }

    async ButtonDown() {
        return !await this.BrainPad.Digital.Read(15, this.BrainPad.Pin.PullUp);
    }

    async ButtonLeft() {
        return !await this.BrainPad.Digital.Read(13, this.BrainPad.Pin.PullUp);
    }

    async ButtonRight() {
        return !await this.BrainPad.Digital.Read(16, this.BrainPad.Pin.PullUp);
    }
}

var Gamer = new BrainGamer(BrainPad);

var player1Pos = 30;
var player2Pos = 30;

var ballPosX = 15;
var ballPosY = 10;
var offsetX = 2;
var offsetY = 2;

var player1Score = 0;
var player2Score = 0;

var winner = false;

await BrainPad.Display.Clear(0);


while (true) {
    await BrainPad.Display.Clear(0);
    await BrainPad.Display.DrawText(player1Score.toString(), 1, 50, 5);
    await BrainPad.Display.DrawText(player2Score.toString(), 1, 70, 5);

    //Move Ball
    ballPosX = ballPosX + offsetX;
    ballPosY = ballPosY + offsetY;

    //Bounce off Walls
    if (ballPosY < 5 || ballPosY > 55) {
        offsetY = offsetY * -1;
    }

    //Draw Ball
    await BrainPad.Display.DrawCircle(1, ballPosX, ballPosY, 3);

    //Check Collision with Player 2
    if (ballPosX > 118) {
        if (ballPosY >= player2Pos - 1 && ballPosY <= player2Pos + 12) {
            //Add code here when player hits ball
            offsetX = offsetX * -1;
            await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
        }
        else {
            //Add code here when player misses ball
            player1Score = player1Score + 1;
            await Gamer.Vibrator(true);
            await BrainPad.System.Wait(100);
            await Gamer.Vibrator(false);
            ballPosX = 15;
        }
    }
    //Check Collision with Player 1
    if (ballPosX < 12) {
        if (ballPosY >= player1Pos - 1 && ballPosY <= player1Pos + 12) {
            //Add code here when player hits ball
            offsetX = offsetX * -1;
            await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
        }
        else {
            //Add code here when player misses ball
            player2Score = player2Score + 1;
            await Gamer.Vibrator(true);
            await BrainPad.System.Wait(100);
            await Gamer.Vibrator(false);
            ballPosX = 115;
        }
    }

    if (player1Score == 5) {
        await BrainPad.Display.Clear(0);
        await BrainPad.Display.DrawTextScale("Player 1", 1, 5, 0, 2, 2);
        await BrainPad.Display.DrawTextScale("WINS!", 1, 25, 20, 2, 2);
        await BrainPad.Display.Show();
        await BrainPad.System.Wait(2000);
        winner = true;
    }

    if (player2Score == 5) {
        await BrainPad.Display.Clear(0);
        await BrainPad.Display.DrawTextScale("Player 2", 1, 5, 0, 2, 2);
        await BrainPad.Display.DrawTextScale("WINS!", 1, 25, 20, 2, 2);
        await BrainPad.Display.Show();
        await BrainPad.System.Wait(2000);
        winner = true;
    }

    if (winner == 1) {
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 200, 100);
        await BrainPad.System.Beep(BrainPad.Pin.Piezo, 256, 100);
        await BrainPad.System.Wait(2000);

        //Reset the game
        player1Pos = 30;
        player2Pos = 30;
        player1Score = 0;
        player2Score = 0;
        ballPosX = 15;
        ballPosY = 10;
        offsetX = 2;
        offsetY = 2;
        winner = 0;
    }


    //Player One
    if (await Gamer.RockerY() < 40) player1Pos = player1Pos - 4;
    if (await Gamer.RockerY() > 60) player1Pos = player1Pos + 4;

    //Player One Stay on Screen
    if (player1Pos < 5) player1Pos = 5;
    if (player1Pos > 50) player1Pos = 50;

    await BrainPad.Display.DrawFillRect(1, 10, player1Pos, 2, 10);

    //Player Two
    if (await Gamer.ButtonUp()) player2Pos = player2Pos - 4;
    if (await Gamer.ButtonDown()) player2Pos = player2Pos + 4;

    //Player Two Stay on Screen
    if (player2Pos < 5) player2Pos = 5;
    if (player2Pos > 50) player2Pos = 50;

    await BrainPad.Display.DrawFillRect(1, 120, player2Pos, 2, 10);

    var net = 0;

    while (net < 64) {
        await BrainPad.Display.DrawLine(1, 64, net, 64, net + 5);
        net = net + 10;
    }

    await BrainPad.Display.Show();
    await BrainPad.System.Wait(10);
}

What’s Next?

Can you give the game Artificial Intelligence and let one of the players be the BrainPad?

BrainStorm

Typically, Video Games require a lot of processing power. Any basic modern computer can surf the web and send emails but modern video games require very sophisticated computers, with special graphics cards. We find it silly that you need a basic computer to do work but then you need an advanced computer to play!

Content Licensing
Newsletter

Twitter Feed
Hot off the press!
January 30, 2024
December 14, 2023
December 11, 2023
December 8, 2023
November 24, 2023