#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const byte b0 = A0; // W / UP
const byte b1 = A1; // A / Left
const byte b2 = A2; // S / Down
const byte b3 = A3; // D / Right
const byte jx = A6; // Joystick Y-Value
const byte jy = A7; // Joystick X-Value
//const byte pot = 10; // Contrast Adjustment
const byte Program_Switch = 13; // Program Switch
//const byte contrast = 7;
const byte fps = 10; // Recommended: 10
const byte pix = 14; // How many game pixels there are in the X-Value
const byte piy = 2; // How many game pixels there are in the Y-Value
byte px; // Initial X position of the player
byte py; // Initial Y position of the player
byte wx1 = 13; // Initial X position of wall 1
byte wy1 = 0; // Initial Y position of wall 1
byte wx2 = 13; // Initial X position of wall 2
byte wy2 = 1; // Initial Y position of wall 2
//byte potpos; // Pot state
bool ps; // Program Switch state
unsigned long startTime = 0; // Variable to store the start time
unsigned long elapsedTime = 0; // Variable to store the elapsed time
unsigned int sec = 0; // Variable to store seconds
unsigned int min = 0; // Variable to store minutes
unsigned long lft = 0; // lft = Last Frame Time
unsigned long fd = 1000 / fps; // fd = Frame Delay
byte program_counter;
byte i;
byte i2;
byte i3;
// Custom character for a filled circle
byte pc[8] = { // Player Character
0b00000,
0b01110,
0b11111,
0b11111,
0b11111,
0b01110,
0b00000,
};
byte clr[8] = { // Clear single pixel
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
0b00000,
};
byte wall[8] = { //Wall
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
0b11111,
};
void setup() {
lcd.begin(16, 2); // Initialize the LCD with the amount of pixels
lcd.setCursor(0, 0);
Serial.begin(9600);
// Load the custom characters into the LCD
lcd.createChar(0, pc); // Player Character
lcd.createChar(1, clr); // Trail Character
lcd.createChar(2, wall); // Wall
//pinMode(contrast, 1);
ps = digitalRead(Program_Switch);
lcd.clear();
}
void loop() {
// Program Selecter
while (program_counter == 0) StartProgram();
while (program_counter == 1) TestProgram();
while (program_counter == 2) JumpGame();
lcd.print("How ");
}
void StartProgram() {
bool a1 = digitalRead(b0);
bool a2 = digitalRead(b1);
bool a3 = digitalRead(b2);
bool a4 = digitalRead(b3);
lcd.setCursor(0, 0);
lcd.print("1: Test ");
lcd.setCursor(0, 1);
lcd.print("2: Jump ");
lcd.setCursor(8, 0);
lcd.print("3: Test ");
lcd.setCursor(8, 1);
lcd.print("4: Next ");
if (a1 == 1) {
program_counter = 1;
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Ready!");
lcd.setCursor(7, 1);
delay(1000);
lcd.print("GO!");
delay(1000);
lcd.clear();
}
else if (a2 == 1) {
program_counter = 2;
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Ready!");
lcd.setCursor(7, 1);
delay(1000);
lcd.print("GO!");
delay(1000);
lcd.clear();
}
else if (a3 == 1) {
program_counter = 3;
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Ready!");
lcd.setCursor(7, 1);
delay(1000);
lcd.print("GO!");
delay(1000);
lcd.clear();
}
else if (a4 == 1) {
program_counter = 4;
lcd.clear();
lcd.setCursor(5, 0);
lcd.print("Ready!");
lcd.setCursor(7, 1);
delay(1000);
lcd.print("GO!");
delay(1000);
lcd.clear();
}
}
void TestProgram() {
// Read button states
bool w = digitalRead(b0);
bool a = digitalRead(b1);
bool s = digitalRead(b2);
bool d = digitalRead(b3);
// Read joystick values
int jxv = analogRead(jx);
int jyv = analogRead(jy);
// UPS calculations
unsigned long ups = millis(); // ups = Updates per second
if (ups - lft >= fd) {
lft = ups;
// Clear the previous player position
lcd.setCursor(px, py);
lcd.write(byte(1));
// Update player position based on button inputs
if (w == 1 && py > 0) py--;
if (a == 1 && px > 0) px--;
if (s == 1 && py < piy - 1) py++;
if (d == 1 && px < pix - 1) px++;
// Map joystick values to movement directions with a threshold
if (jyv < 100 && py > 0) py--;
if (jxv < 100 && px > 0) px--;
if (jyv > 900 && py < piy - 1) py++;
if (jxv > 900 && px < pix - 1) px++;
// Move the cursor to the new player position
lcd.setCursor(px, py);
// Display the player character
lcd.write(byte(0));
// Check if the timer has started
if (startTime == 0) {
startTime = millis(); // If not, start the timer
}
// Calculate the elapsed time
elapsedTime = millis() - startTime;
// Calculate seconds and minutes
sec = (elapsedTime / 1000) % 60;
min = elapsedTime / 60000;
// Display timer in the last two columns of the LCD
lcd.setCursor(14, 0); // Top row for seconds
lcd.print(sec < 10 ? "0" + String(sec) : String(sec));
lcd.setCursor(14, 1); // Bottom row for minutes
lcd.print(min < 10 ? "0" + String(min) : String(min));
}
}
void JumpGame() {
if (i == 0) {
px = 0;
py = 1;
i++;
}
// Read button states
bool w = digitalRead(b0);
bool a = digitalRead(b1);
bool s = digitalRead(b2);
bool d = digitalRead(b3);
// UPS calculations
unsigned long ups = millis(); // ups = Updates per second
if (ups - lft >= fd / 3) {
lft = ups;
// Clear the previous player position
lcd.setCursor(px, py);
lcd.write(byte(1));
// Update player position based on button inputs
if (w == 1 && py == 1) py--;
else if (a == 1 && py == 1) py--;
else if (s == 1 && py == 1) py--;
else if (d == 1 && py == 1) py--;
Serial.println(py);
if (py < 1 || py > 100) {
i++;
if (i > 15) {
py = 1;
i = 1;
}
}
// Update player position
lcd.setCursor(px, py);
lcd.write(byte(0));
// Update wall position
lcd.setCursor(wx1, wy1);
lcd.write(byte(1));
lcd.setCursor(wx2, wy2);
lcd.write(byte(1));
i2++;
i3++;
// Add movement to the walls and make it so that if the x and y values of the player is the same as any of the walls its triggers game over
lcd.setCursor(wx1, wy1);
lcd.write(byte(2));
lcd.setCursor(wx2, wy2);
lcd.write(byte(2));
}
}