Someone requested that I make the game Pong on a 16 x 2 LCD panel and so I start doing that in this tutorial. I’m going to live code everything with no preparation ahead of time, so that you can see how I solve this problem.
I focus this time on drawing on the LCD panel, moving the paddles and processing user input along with much more. All of the code and a transcript are found below.
If you like videos like this, consider donating $1, or simply turn off Ad Blocking software. Either allows me to afford the books and components required to make these videos.
Code from the Video
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Holds paddle data in 2 separate arrays for easy
// character printing
// Characters LEDs are turned on by marking them as
// boolean true or false and then converting from binary
// to base 10 16 = 10000 where binary digits go 16 8 4 2 1
//
byte aiPaddleArray[2][8] = {0,0,0,0,0,1,1,1};
byte myPaddleArray[2][8] = {0,0,0,0,0,16,16,16};
// Used to make logic easier for when moving paddles
byte aiPaddleColArray[16] = {0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0};
byte myPaddleColArray[16] = {0,0,0,0,0,16,16,16,0,0,0,0,0,0,0,0};
// Holds middle pixel for each paddle
byte aiPaddlePos = 6;
byte myPaddlePos = 6;
// Buttons that move the paddle
const int moveRightButton = 8;
const int moveLeftButton = 7;
// Stores whether buttons have been pressed
int rightButState = 0;
int leftButState = 0;
// Store previous button state so we only count input once
int rightLastButState = 0;
int leftLastButState = 0;
// 0 out all the paddle leds
void ClearPaddles(){
for(int i = 0; i < 2; i++){
for(int j = 0; j < 8; j++){
aiPaddleArray[i][j] = 0;
myPaddleArray[i][j] = 0;
}
}
}
void PrintPaddles(){
// Grab the character array stored in myPaddleArray using a pointer
byte* mPTemp1 = myPaddleArray[0];
byte* mPTemp2 = myPaddleArray[1];
byte* aiPTemp1 = aiPaddleArray[0];
byte* aiPTemp2 = aiPaddleArray[1];
// Each character must have a unique character ID and array to print
lcd.createChar(0, mPTemp1);
lcd.createChar(1, mPTemp2);
lcd.createChar(2, aiPTemp1);
lcd.createChar(3, aiPTemp2);
// Move cursor to 13 column on the 1st row
lcd.setCursor(14, 0);
// Draw the character
lcd.write(byte(0));
lcd.setCursor(14, 1);
lcd.write(byte(1));
lcd.setCursor(1, 0);
lcd.write(byte(2));
lcd.setCursor(1, 1);
lcd.write(byte(3));
for(int i = 0; i < 8; i++){
Serial.println(mPTemp1[i]);
}
}
// Clear paddle characters and then add character data
void SetupPaddles(){
ClearPaddles();
myPaddleArray[0][5] = 16;
myPaddleArray[0][6] = 16;
myPaddleArray[0][7] = 16;
aiPaddleArray[0][5] = 1;
aiPaddleArray[0][6] = 1;
aiPaddleArray[0][7] = 1;
PrintPaddles();
}
void MovePaddleUp(){
// Make sure the paddle can't go off the board
if(myPaddlePos != 1){
// Decrementing the paddle moves it up
myPaddlePos--;
UpdatePaddlesAfterMove();
}
}
void MovePaddleDown(){
if(myPaddlePos != 14){
myPaddlePos++;
UpdatePaddlesAfterMove();
}
}
void UpdatePaddlesAfterMove(){
// Cycle through all bools turning on the next 1 above and off the 1 below
for(int i = 0; i < 16; i++){
if((i == (myPaddlePos-1)) || (i == myPaddlePos) || (i == (myPaddlePos+1))){
myPaddleColArray[i] = 16;
} else {
myPaddleColArray[i] = 0;
}
}
// Update the arrays used for printing the paddle characters
for(int j = 0; j < 8; j++){
myPaddleArray[0][j] = myPaddleColArray[j];
}
for(int k = 8; k < 16; k++){
myPaddleArray[1][k-8] = myPaddleColArray[k];
}
}
void setup() {
Serial.begin(9600);
// State that the display has 2 rows with 16
// characters per row
lcd.begin(16, 2);
// Setup buttons so we can receive input
pinMode(moveRightButton, INPUT);
pinMode(moveLeftButton, INPUT);
// Print paddles on the screen
SetupPaddles();
}
void loop() {
// Get current button state
rightButState = digitalRead(moveRightButton);
leftButState = digitalRead(moveLeftButton);
1
// Check the button state change
if(rightButState != rightLastButState){
// Check if button was pressed
if(rightButState == HIGH){
// Move paddle up if you can and redraw
MovePaddleUp();
PrintPaddles();
}
// Added to avoid bouncing
delay(50);
// Store last button state
rightLastButState = rightButState;
}
// Check the button state change
if(leftButState != leftLastButState){
// Check if button was pressed
if(leftButState == HIGH){
// Move paddle up if you can and redraw
MovePaddleDown();
PrintPaddles();
}
// Added to avoid bouncing
delay(50);
// Store last button state
leftLastButState = leftButState;
}
}