# 06 Arduino How? Let’s Make the Paddle Bounce the Pong Ball

Date:  May 21, 2017

/* Notes:  If you want to read the previous 5 blog posts on how to make a Pong game on Arduino, you can just search “miniliew Arduino How” on either google or the Miniliew website */

In the last lesson, you manage to draw the paddle.  By turning the potentiometer, you are able to move the paddle.  And you notice, the paddle cannot bounce the ball because we have not implement the bouncing behaviour to the paddle yet.

This should be the last lesson for creating a Pong game using Arduino.

• We will make the paddle to bounce the Pong Ball
• We also will make a different sound if you miss bouncing the Pong Ball

Let’s get started.

By now, you should have removed the right wall so that it does not bounce anything.

You also have already have a movable paddle that you can try to bounce the pong ball.

So, all you need to add in your Movement() code block is that, if the ballX position has > then your paddle surface (i.e. screen width 128 -1 – paddle’s width) and if the ballY falls between paddlePositionA & paddle PositionA + paddle’s height, then, you bounce the ball back by negating the ballMoveX (multiply by -1 so that it will start deducting the x-position).

```if (ballX >= SCREEN_WIDTH - 1 - PADDLE_WIDTH - BALL_SIZE/2 && ballSpeedX > 0) {
ballMoveX *= -1;
soundBounce();
}
}```

That will do the trick.

Now, what if the ballY is outside of the paddle, then, you will reset a ballX.   You don’t have to reset the ballY, so that it will always restart at the y-axis position when the ball last touch the paddle, make it seems like random.

So, you will need a routine to check that.

``` // score point
if (ballX >= SCREEN_WIDTH - 1 - BALL_SIZE/2) {
if (ballSpeedX > 0) {
scoreA++;
ballX = 32; // only reset the x-axis, retain the y-axis
}
soundPoint();
}

Don’t forget to write a soundPoint() function which sound a different tone.

```void soundPoint()
{
tone(BEEPER, NOTE_D3, 150);
}```

That’s it.  As simple as it is.

So, now you got a working Pong game.

Very simple logic of programming.  Not hard at all.

And here are some of the improvement you might want to do.

• Print scores
• add effect if you hit the ball while paddle is moving, sound a different sound, add speed, or slow down like a slide ball, etc.
• You can try to program an AI (Artificial Intelligent) that means you will need to remove another wall and add Paddle B.
• You can add another potentiometer so that you can have two player games.
• You can make it into a Squash game too.
• Or you make it to 4-paddle Hockey game.

So, it is up to you what you want to design.  I ported a Pong game from the Internet and I quite like it.  Take a look.  I actually ported the source code to make it run on my DIYMall 0.96″ OLED, and I also make use of the multiple digital pin to change the game mode to Single player mode (Vs. AI) or Two players mode, and I can change it to play either the Pong game, Hockey game or the Squash game.  This is how coding add some spices into my life.  Check out this game.

The source code for today’s work is as follow.

```#include <Arduino.h>
#include <U8g2lib.h>
#include "pitches.h"

#ifdef U8X8_HAVE_HW_SPI
#include <SPI.h>
#endif
#ifdef U8X8_HAVE_HW_I2C
#include <Wire.h>
#endif

U8G2_SSD1306_128X64_NONAME_1_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

#define BALL_SIZE 4
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define BEEPER 8 // connect the beeper to digital input pin #8

#define BALL_MOVEX 4 // when you move your pong ball, how far x-axis it should move from last position
#define BALL_MOVEY 2 // when you move your ping ball, how far y-axis it should move from last position

#define CONTROL_A A0 // Potentiometer reading the Analog pin A0

int controlA;
int ballSpeedX = BALL_MOVEX;
int ballSpeedY = BALL_MOVEY;
int scoreA = 0;

int ballX = SCREEN_WIDTH/2; // start to "drop" the pong ball from center of x-axis
int ballY = BALL_SIZE/2+1; // start to "drop" the pong ball from top
int ballMoveX = BALL_MOVEX;
int ballMoveY = BALL_MOVEY;

void draw(void) {

// draw playing area
u8g2.drawVLine(0,0,64);
u8g2.drawHLine(0,0,128);
u8g2.drawHLine(0,63,128);

// draw ball
u8g2.drawDisc(ballX,ballY,BALL_SIZE/2);

u8g2.setFont(u8g2_font_helvB08_tf);
u8g2.setCursor(20,45);
u8g2.print(ballX);
u8g2.setCursor(50,45);
u8g2.print(ballY);

u8g2.setFont(u8g2_font_helvB08_tf);
u8g2.setCursor(20,30);

u8g2.setCursor(50,30);
u8g2.print(controlA);

}

void Movement(){

// Read the analog value from the potentiometer

// Map the analog range to the screen height minus the paddle's height
// paddlePositionA is the starting y-axis of the paddle to be drawn

// If you minus the last postion and the new position of the tip of paddle, that will give you the paddle speed

// the pong ball move from last position in terms of x-axis and y-axis with these differnce
ballX = ballX + ballMoveX;
ballY = ballY + ballMoveY;

// ball bouncing from top or bottom
if (ballY >= SCREEN_HEIGHT - 3 - BALL_SIZE/2 || ballY <= 2 + BALL_SIZE/2) {
ballMoveY *= -1; // instead of adding, reverse the polarity, start to minus
soundBounce();
}

// ball bouncing from left wall inly
if (ballX <= 2 + BALL_SIZE/2) {
ballMoveX *= -1; // instead of adding, revrse the polarity, start to minus
soundBounce();
}

// ball boucing from the paddle
// First, you check if the ball x-axis has passed the paddle surface, and
if (ballX >= SCREEN_WIDTH - 1 - PADDLE_WIDTH - BALL_SIZE/2 && ballSpeedX > 0) {
// if the ball y-axis is within the range of the paddle height
ballMoveX *= -1;
soundBounce();
}
}

// score point
if (ballX >= SCREEN_WIDTH - 1 - BALL_SIZE/2) {
if (ballSpeedX > 0) {
scoreA++;
ballX = 32; // only reset the x-axis, retain the y-axis
}
soundPoint();
}
}

void soundBounce()
{
tone(BEEPER, NOTE_B4, 50);
}

void soundPoint()
{
tone(BEEPER, NOTE_D3, 150);
}

void setup(void) {
u8g2.begin(); // initialise the display
}

void loop(void) {
Movement();
u8g2.firstPage();
do {
draw();
} while (u8g2.nextPage());
// delay(200); // for troubleshooting purpose, make the ball move slowly
}

```