项目代码 
 
 
			
			
			#include <Wire.h>
 #include <LiquidCrystal_I2C.h>
 
 // Initialize the LCD, set the address to 0x27 or 0x3F depending on your module
 LiquidCrystal_I2C lcd(0x27, 16, 2);  // 16 columns, 2 rows
 
 // Pin setup
 int ledPins[] = {4, 5, 6, 7, 8, 9, 10, 11, 12, 13};  // Pins for the 8 LEDs
 int buttonPin = 2;  // Pin for the button
 int buzzerPin = 3;  // Pin for the piezo buzzer
 int middleLED = 5;   // The middle LED position (adjust if needed)
 int direction = 1;   // Initial direction (1 = forward, -1 = backward)
 int currentLED = 0;  // Start at the first LED
 int level = 1;       // Start at level 1
 int delayTime = 300; // Initial delay time for LED movement (in ms)
 int score = 0;       // Player score
 int levelTime = 10;  // Time allowed for each level (in seconds)
 unsigned long startTime;  // Time when the level starts
 unsigned long lastMoveTime = 0;  // Time when the LEDs last moved
 unsigned long lastToneTime = 0;  // Time to control the duration of the tone
 unsigned long buttonDebounceTime = 0; // For button debouncing
 unsigned long debounceDelay = 50;     // Debounce delay in milliseconds
 
 int lastRemainingTime = -1; // To track the last displayed time
 int lastLevel = -1;         // To track the last displayed level
 int lastScore = -1;         // To track the last displayed score
 
 bool buttonPressed = false;
 bool tonePlaying = false;  // Flag to indicate whether the tone is currently playing
 bool gameEnded = false;    // Flag to indicate the end of the game
 
 // Function to play a tone non-blocking
 void startTone(int frequency) {
   tone(buzzerPin, frequency);  // Start playing the tone
   tonePlaying = true;          // Set tone playing flag
   lastToneTime = millis();     // Record when the tone started
 }
 
 void stopTone() {
   noTone(buzzerPin);           // Stop playing the tone
   tonePlaying = false;         // Reset tone playing flag
 }
 
 void setup() {
   // Initialize the LCD
   lcd.init();
   lcd.backlight();
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("HUNTER Game");
   delay(2000);  // Display the welcome message for 2 seconds
 
   // Pin configurations
   for (int i = 0; i < 10; i++) {
     pinMode(ledPins[i], OUTPUT);  // Set all LED pins as outputs
   }
   pinMode(buttonPin, INPUT_PULLUP);  // Set button pin as input with pullup
   pinMode(buzzerPin, OUTPUT);  // Set buzzer pin as output
   
   Serial.begin(9600);  // Start serial for debugging
   Serial.println("Welcome to the Knight Rider Hunter Game!");
   
   lcd.clear();
   displayStatus();  // Display the initial level, score, and time
   startTime = millis();  // Record when the level starts
   lastMoveTime = millis();  // Initialize the last move time
 }
 
 void loop() {
   // If the game has ended, stop further operations
   if (gameEnded) {
     return;
   }
 
   // Check if the timer has expired
   unsigned long elapsedTime = (millis() - startTime) / 1000;
   int remainingTime = levelTime - elapsedTime;
 
   // If time has run out, end the game
   if (remainingTime <= 0) {
     endGame();  // Call the function to end the game
     return;     // Stop further execution
   }
 
   // Handle LED movement (non-blocking using millis)
   if (millis() - lastMoveTime >= delayTime) {
     moveLED();
     lastMoveTime = millis();  // Reset the last move time
     startTone(1000);  // Start playing the 1000Hz tone when moving LED
   }
 
   // Stop the tone after 50ms
   if (tonePlaying && millis() - lastToneTime >= 50) {
     stopTone();  // Stop the tone after 50ms
   }
 
   // Check if the button is pressed (with debouncing)
   int buttonState = digitalRead(buttonPin);
   if (buttonState == LOW && millis() - buttonDebounceTime > debounceDelay) {
     buttonDebounceTime = millis();  // Reset debounce timer
     if (currentLED == middleLED) {
       Serial.println("You win this level!");
       score++;  // Increase score for a successful hit
       startTone(2000);  // Play victory tone
       delay(500);  // Play for 500ms
       stopTone();
       levelUp();  // Go to the next level
     } else {
       Serial.println("Missed! Try again.");
       startTone(500);  // Play fail sound
       delay(300);  // Play for 300ms
       stopTone();
     }
     delay(500);  // Short pause after button press
   }
 
   // Update LCD with the remaining time and score only if there's a change
   if (remainingTime != lastRemainingTime || level != lastLevel || score != lastScore) {
     displayStatus();
     lastRemainingTime = remainingTime;
     lastLevel = level;
     lastScore = score;
   }
 }
 
 // Function to move the LEDs
 void moveLED() {
   // Turn off all LEDs
   for (int i = 0; i < 10; i++) {
     digitalWrite(ledPins[i], LOW);
   }
 
   // Light up the current LED
   digitalWrite(ledPins[currentLED], HIGH);
 
   // Move the LED in the current direction
   currentLED += direction;
 
   // Reverse direction if we reach the end of the LED array
   if (currentLED == 9 || currentLED == 0) {
     direction = -direction;
   }
 }
 
 // Function to advance to the next level
 void levelUp() {
   level++;  // Increase the level
   delayTime -= 30;  // Decrease delay time to make LEDs move faster
 
   // Ensure delayTime doesn't go below a certain threshold (e.g., 50 ms)
   if (delayTime < 50) {
     delayTime = 50;
   }
 
   Serial.print("Level Up! Now at Level: ");
   Serial.println(level);
   Serial.print("New LED Speed (ms): ");
   Serial.println(delayTime);
 
   // Play level-up sound
   startTone(1500);  // Play a tone at 1.5kHz
   delay(300);       // Play for 300ms
   stopTone();
   delay(1000);  // Give a 1-second pause before starting the next level
 
   // Reset the timer for the next level
   startTime = millis();
 }
 
 // Function to display the current level, score, and remaining time
 void displayStatus() {
   // Calculate the remaining time in seconds
   unsigned long elapsedTime = (millis() - startTime) / 1000;  // Convert to seconds
   int remainingTime = levelTime - elapsedTime;  // Calculate the remaining time
   
   // Ensure the remaining time does not go negative
   if (remainingTime < 0) {
     remainingTime = 0;
   }
   
   lcd.setCursor(0, 0);
   lcd.print("Lvl:");
   lcd.print(level);
 
   lcd.setCursor(6, 0);
   lcd.print("Time:");
   lcd.print(remainingTime);  // Correctly print the remaining time in seconds
   
   // Clear any leftover characters by overwriting with a space
   if (remainingTime < 10) {
     lcd.print(" ");  // Overwrite the extra digit when remainingTime is a single digit
   }
 
   lcd.setCursor(0, 1);
   lcd.print("Score:");
   lcd.print(score);
 }
 
 
 
 // Function to end the game when the timer runs out
 void endGame() {
   gameEnded = true;  // Set the flag to end the game
 
   // Turn off all LEDs
   for (int i = 0; i < 8; i++) {
     digitalWrite(ledPins[i], LOW);
   }
 
   // Display "End Game" and the final score on the LCD
   lcd.clear();
   lcd.setCursor(0, 0);
   lcd.print("End Game");
   lcd.setCursor(0, 1);
   lcd.print("Score:");
   lcd.print(score);
 
   // Play a sound to indicate the game has ended
   startTone(300);  // Play a low tone
   delay(1000);     // Play for 1 second
   stopTone();
 
   // Wait for 3 seconds before starting a new game
   delay(3000);
 
   // Restart the game
   resetGame();
 }
 
 // Function to reset the game and start a new one
 void resetGame() {
   gameEnded = false;  // Reset the game end flag
   score = 0;          // Reset the score to 0
   level = 1;          // Reset the level to 1
   delayTime = 300;    // Reset the delay time for LED movement
   startTime = millis();  // Reset the timer
 
   // Clear the LCD and display the initial status
   lcd.clear();
   displayStatus();
 
   Serial.println("New game started!");
   
   // Restart the LED movement immediately
   lastMoveTime = millis();
 }
 复制代码