Components and supplies
Arduino Nano
Piezo Buzzer
Push Button
16x2 LCD display with I²C interface
Resistor 470 ohm
3 mm LED: Yellow
Resistor 10k
Tools and machines
Soldering kit
Apps and platforms
Arduino IDE
Project description
Code
Code
cpp
...
1#include <Wire.h> 2#include <LiquidCrystal_I2C.h> 3 4// Initialize the LCD, set the address to 0x27 or 0x3F depending on your module 5LiquidCrystal_I2C lcd(0x27, 16, 2); // 16 columns, 2 rows 6 7// Pin setup 8int ledPins[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13}; // Pins for the 8 LEDs 9int buttonPin = 2; // Pin for the button 10int buzzerPin = 3; // Pin for the piezo buzzer 11int middleLED = 5; // The middle LED position (adjust if needed) 12int direction = 1; // Initial direction (1 = forward, -1 = backward) 13int currentLED = 0; // Start at the first LED 14int level = 1; // Start at level 1 15int delayTime = 300; // Initial delay time for LED movement (in ms) 16int score = 0; // Player score 17int levelTime = 10; // Time allowed for each level (in seconds) 18unsigned long startTime; // Time when the level starts 19unsigned long lastMoveTime = 0; // Time when the LEDs last moved 20unsigned long lastToneTime = 0; // Time to control the duration of the tone 21unsigned long buttonDebounceTime = 0; // For button debouncing 22unsigned long debounceDelay = 50; // Debounce delay in milliseconds 23 24int lastRemainingTime = -1; // To track the last displayed time 25int lastLevel = -1; // To track the last displayed level 26int lastScore = -1; // To track the last displayed score 27 28bool buttonPressed = false; 29bool tonePlaying = false; // Flag to indicate whether the tone is currently playing 30bool gameEnded = false; // Flag to indicate the end of the game 31 32// Function to play a tone non-blocking 33void startTone(int frequency) { 34 tone(buzzerPin, frequency); // Start playing the tone 35 tonePlaying = true; // Set tone playing flag 36 lastToneTime = millis(); // Record when the tone started 37} 38 39void stopTone() { 40 noTone(buzzerPin); // Stop playing the tone 41 tonePlaying = false; // Reset tone playing flag 42} 43 44void setup() { 45 // Initialize the LCD 46 lcd.init(); 47 lcd.backlight(); 48 lcd.clear(); 49 lcd.setCursor(0, 0); 50 lcd.print("HUNTER Game"); 51 delay(2000); // Display the welcome message for 2 seconds 52 53 // Pin configurations 54 for (int i = 0; i < 10; i++) { 55 pinMode(ledPins[i], OUTPUT); // Set all LED pins as outputs 56 } 57 pinMode(buttonPin, INPUT_PULLUP); // Set button pin as input with pullup 58 pinMode(buzzerPin, OUTPUT); // Set buzzer pin as output 59 60 Serial.begin(9600); // Start serial for debugging 61 Serial.println("Welcome to the Knight Rider Hunter Game!"); 62 63 lcd.clear(); 64 displayStatus(); // Display the initial level, score, and time 65 startTime = millis(); // Record when the level starts 66 lastMoveTime = millis(); // Initialize the last move time 67} 68 69void loop() { 70 // If the game has ended, stop further operations 71 if (gameEnded) { 72 return; 73 } 74 75 // Check if the timer has expired 76 unsigned long elapsedTime = (millis() - startTime) / 1000; 77 int remainingTime = levelTime - elapsedTime; 78 79 // If time has run out, end the game 80 if (remainingTime <= 0) { 81 endGame(); // Call the function to end the game 82 return; // Stop further execution 83 } 84 85 // Handle LED movement (non-blocking using millis) 86 if (millis() - lastMoveTime >= delayTime) { 87 moveLED(); 88 lastMoveTime = millis(); // Reset the last move time 89 startTone(1000); // Start playing the 1000Hz tone when moving LED 90 } 91 92 // Stop the tone after 50ms 93 if (tonePlaying && millis() - lastToneTime >= 50) { 94 stopTone(); // Stop the tone after 50ms 95 } 96 97 // Check if the button is pressed (with debouncing) 98 int buttonState = digitalRead(buttonPin); 99 if (buttonState == LOW && millis() - buttonDebounceTime > debounceDelay) { 100 buttonDebounceTime = millis(); // Reset debounce timer 101 if (currentLED == middleLED) { 102 Serial.println("You win this level!"); 103 score++; // Increase score for a successful hit 104 startTone(2000); // Play victory tone 105 delay(500); // Play for 500ms 106 stopTone(); 107 levelUp(); // Go to the next level 108 } else { 109 Serial.println("Missed! Try again."); 110 startTone(500); // Play fail sound 111 delay(300); // Play for 300ms 112 stopTone(); 113 } 114 delay(500); // Short pause after button press 115 } 116 117 // Update LCD with the remaining time and score only if there's a change 118 if (remainingTime != lastRemainingTime || level != lastLevel || score != lastScore) { 119 displayStatus(); 120 lastRemainingTime = remainingTime; 121 lastLevel = level; 122 lastScore = score; 123 } 124} 125 126// Function to move the LEDs 127void moveLED() { 128 // Turn off all LEDs 129 for (int i = 0; i < 10; i++) { 130 digitalWrite(ledPins[i], LOW); 131 } 132 133 // Light up the current LED 134 digitalWrite(ledPins[currentLED], HIGH); 135 136 // Move the LED in the current direction 137 currentLED += direction; 138 139 // Reverse direction if we reach the end of the LED array 140 if (currentLED == 9 || currentLED == 0) { 141 direction = -direction; 142 } 143} 144 145// Function to advance to the next level 146void levelUp() { 147 level++; // Increase the level 148 delayTime -= 30; // Decrease delay time to make LEDs move faster 149 150 // Ensure delayTime doesn't go below a certain threshold (e.g., 50 ms) 151 if (delayTime < 50) { 152 delayTime = 50; 153 } 154 155 Serial.print("Level Up! Now at Level: "); 156 Serial.println(level); 157 Serial.print("New LED Speed (ms): "); 158 Serial.println(delayTime); 159 160 // Play level-up sound 161 startTone(1500); // Play a tone at 1.5kHz 162 delay(300); // Play for 300ms 163 stopTone(); 164 delay(1000); // Give a 1-second pause before starting the next level 165 166 // Reset the timer for the next level 167 startTime = millis(); 168} 169 170// Function to display the current level, score, and remaining time 171void displayStatus() { 172 // Calculate the remaining time in seconds 173 unsigned long elapsedTime = (millis() - startTime) / 1000; // Convert to seconds 174 int remainingTime = levelTime - elapsedTime; // Calculate the remaining time 175 176 // Ensure the remaining time does not go negative 177 if (remainingTime < 0) { 178 remainingTime = 0; 179 } 180 181 lcd.setCursor(0, 0); 182 lcd.print("Lvl:"); 183 lcd.print(level); 184 185 lcd.setCursor(6, 0); 186 lcd.print("Time:"); 187 lcd.print(remainingTime); // Correctly print the remaining time in seconds 188 189 // Clear any leftover characters by overwriting with a space 190 if (remainingTime < 10) { 191 lcd.print(" "); // Overwrite the extra digit when remainingTime is a single digit 192 } 193 194 lcd.setCursor(0, 1); 195 lcd.print("Score:"); 196 lcd.print(score); 197} 198 199 200 201// Function to end the game when the timer runs out 202void endGame() { 203 gameEnded = true; // Set the flag to end the game 204 205 // Turn off all LEDs 206 for (int i = 0; i < 8; i++) { 207 digitalWrite(ledPins[i], LOW); 208 } 209 210 // Display "End Game" and the final score on the LCD 211 lcd.clear(); 212 lcd.setCursor(0, 0); 213 lcd.print("End Game"); 214 lcd.setCursor(0, 1); 215 lcd.print("Score:"); 216 lcd.print(score); 217 218 // Play a sound to indicate the game has ended 219 startTone(300); // Play a low tone 220 delay(1000); // Play for 1 second 221 stopTone(); 222 223 // Wait for 3 seconds before starting a new game 224 delay(3000); 225 226 // Restart the game 227 resetGame(); 228} 229 230// Function to reset the game and start a new one 231void resetGame() { 232 gameEnded = false; // Reset the game end flag 233 score = 0; // Reset the score to 0 234 level = 1; // Reset the level to 1 235 delayTime = 300; // Reset the delay time for LED movement 236 startTime = millis(); // Reset the timer 237 238 // Clear the LCD and display the initial status 239 lcd.clear(); 240 displayStatus(); 241 242 Serial.println("New game started!"); 243 244 // Restart the LED movement immediately 245 lastMoveTime = millis(); 246}
Downloadable files
Schematic
with 10 resistors
Schematic with 10 Resistors.jpg
Comments
Only logged in users can leave comments