驴友花雕 发表于 3 天前

【Arduino 动手做】使用 Arduino DIY 简单的 猎人 LED 游戏

这是《猎人》游戏的定制版本,配有 10 个 LED 和 LCD 显示屏来显示分数,并伴随各种音效。

前段时间,我给大家介绍了一款简单易做却又趣味十足的游戏——用 Arduino 和 10 个 LED 灯制作的“乒乓球”一维模拟游戏。这次,我将使用同样的硬件,并进行少量的引脚排列改动,向大家展示如何制作一款同样有趣且令人上瘾的游戏——“猎人”。游戏的目标是在预设的 LED 灯亮起时按下按钮,即可得分。


这是 Hunter 的改进版,有两个 LED 灯标示目标。目标 LED 灯为蓝色,箭头指示其激活的移动方向。LED 灯的“移动”方式类似于“夜骑士”特效,第一个目标(LED)从左向右移动时处于激活状态,第二个目标(LED)则相反,从右向左移动时处于激活状态。

有关比赛和比分的信息显示在 16x2 LCD 显示屏上。

第一关最简单,之后每关LED灯的移动速度都会加快。每关我们有10秒的时间击中目标。每过一关,我们都会得一分。如果10秒内未能击中目标,游戏就会结束,分数会显示在屏幕上,三秒后开始新的游戏。LED灯移动、击中目标以及游戏结束时,小型蜂鸣器会发出相应的不同声音。



驴友花雕 发表于 3 天前

【Arduino 动手做】使用 Arduino DIY 简单的 HUNTER LED 游戏

正如我之前提到的,这个游戏制作起来非常简单,只包含几个组件:

Arduino Nano微控制器板
I2C LCD显示屏 16x2
10个LED
2 个按钮(仅一个就足够了,但在这种情况下,它们是并联的,因为它们是上一个项目中保留下来的)
蜂鸣器
以及十个 470 欧姆的电阻器来限制 LED 的电流
这里需要说明的是,您也可以只使用一个电阻来控制所有 LED。



驴友花雕 发表于 3 天前

【Arduino 动手做】使用 Arduino DIY 简单的 HUNTER LED 游戏

在本项目中,同一时刻不会点亮多个二极管。在这种特殊情况下,我们将阳极直接连接到 Arduino 引脚,阴极相互连接,并通过一个 470 欧姆的串联电阻接地(负极)。此方案的原理图如下所示。

现在让我们看看这个装置在现实中是如何工作的:游戏开始时,LED灯会像夜骑手一样从左到右移动。现在,你需要在其中一个蓝色目标LED灯亮起的瞬间按下其中一个按钮。如果操作成功,我们将进入下一关,此时LED灯会以更快的速度移动。如果我们在10秒内未能击中目标,游戏将结束并显示最终得分,三秒后将开始新的游戏。









驴友花雕 发表于 3 天前

【Arduino 动手做】使用 Arduino DIY 简单的 HUNTER LED 游戏

项目代码

#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, 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, LOW);
}

// Light up the current LED
digitalWrite(ledPins, 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, 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();
}


驴友花雕 发表于 3 天前

【Arduino 动手做】使用 Arduino DIY 简单的 HUNTER LED 游戏

附录
【Arduino 动手做】使用 Arduino DIY 简单的 HUNTER LED 游戏
项目链接:https://www.hackster.io/mircemk/diy-simple-hunter-led-game-with-arduino-18f21f
项目作者:北马其顿 米尔塞姆克(Mirko Pavleski)

项目视频 :https://www.youtube.com/watch?v=CsotpFYwgLc
项目代码:https://www.hackster.io/code_files/662114/download



页: [1]
查看完整版本: 【Arduino 动手做】使用 Arduino DIY 简单的 猎人 LED 游戏