35浏览
查看: 35|回复: 4

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

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

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


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

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

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

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

驴友花雕  中级技神
 楼主|

发表于 昨天 10:21

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

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

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

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

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 10:23

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

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

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

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

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

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

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

回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 10:24

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

项目代码

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


回复

使用道具 举报

驴友花雕  中级技神
 楼主|

发表于 昨天 10:28

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

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

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

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

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

为本项目制作心愿单
购买心愿单
心愿单 编辑
[[wsData.name]]

硬件清单

  • [[d.name]]
btnicon
我也要做!
点击进入购买页面
上海智位机器人股份有限公司 沪ICP备09038501号-4 备案 沪公网安备31011502402448

© 2013-2025 Comsenz Inc. Powered by Discuz! X3.4 Licensed

mail