Я пытаюсь создать игру Whack-A-Mole, используя Arduino Mega с 10 светодиодами (Moles) и 10 кнопками (Whack). Электроника доработана и проверена, все работает нормально. К нему также подключено радио BLE, которое предлагает доске начать одну из трех игр, которые я планирую сделать.
Проблема, с которой я столкнулся, заключается в следующем:
В основном цикле я прослушиваю команду из приложения, поступающую через BLE. Когда приложение отправляет «1» (последовательная передача), я вызываю функцию
playGameOne ();
Главное, что в основном цикле все работает нормально, но когда я перехожу к игровой функции, она запускается один раз и снова возвращается в основной цикл. Как я могу заставить пользователя зацикливаться на функции игры, пока игра не закончится? Ох - и я не пытаюсь использовать какие-либо прерывания, но я полагаю, что это один из способов сделать это.
Последнее воплощение игровой функции выглядит так:
//////////////////////////////////////////////
////////////////// GAME 1 //////////////////
void gameOne(){
//var int eTime;
// inform player game is about to begin
playCountdown();
Serial.println("Game Begun");
// initialize var to count time
elapsedMillis timeElapsed;
if (gameState < 1){
gameOneOne();
Serial.print("Game finished - Your time: ");
Serial.println(timeElapsed);
}
}
void gameOneOne(){
while(digitalRead(btPin31) == LOW){
// turn on LED45
digitalWrite(ledPin45, HIGH);
// wait for user to push corresponding button
if (digitalRead(btPin31) == HIGH){
// turn off the LED and jump to next LED - gameOneTwo()
digitalWrite(ledPin45, LOW);
gameOneTwo();
}
}
}
void gameOneTwo(){
while(digitalRead(btPin39) == LOW){
// turn on LED53
digitalWrite(ledPin53, HIGH);
if (digitalRead(btPin39) == HIGH){
digitalWrite(ledPin53, LOW);
// Finish the game, set state to 1
gameState = 1;
}
}
}
Мало того, что это не работает, я очень сомневаюсь, что это правильный способ кодирования игр. Фактически, идеальным было бы иметь игровой скрипт, который можно было бы загружать динамически. Скрипт игры будет выглядеть так:
Header {name of game}
45 {pin of first LED}
500 {how long to keep it on, in ms}
49 {pin of the second LED}
500 {how long to keep it on, in ms}
... and so on
End of File
Каков лучший ресурс, чтобы изучить это должным образом.
РЕДАКТИРОВАТЬ
Вот мой основной цикл
// included header files
#include <elapsedMillis.h> // Measuring Elapsed Time Library
// Constant - Piezzo Speaker Pin
const int beepPin = 11; // the number of the Piezo Spkr pin
// Constants - Button Pins
const int btPin30 = 30;
const int btPin31 = 31;
const int btPin32 = 32;
const int btPin33 = 33;
const int btPin34 = 34;
const int btPin35 = 35;
const int btPin36 = 36;
const int btPin37 = 37;
const int btPin38 = 38;
const int btPin39 = 39;
// Constants - LED Pins
const int ledPin53 = 53;
const int ledPin52 = 52;
const int ledPin51 = 51;
const int ledPin50 = 50;
const int ledPin49 = 49;
const int ledPin48 = 48;
const int ledPin47 = 47;
const int ledPin46 = 46;
const int ledPin45 = 45;
const int ledPin44 = 44;
//Variable for storing BLUETOOTH received data
char data = 0;
// variables will change:
int buttonState = 0; // variable for reading the pushbutton status
int btPin30State = 0;
int btPin31State = 0;
int btPin32State = 0;
int btPin33State = 0;
int btPin34State = 0;
int btPin35State = 0;
int btPin36State = 0;
int btPin37State = 0;
int btPin38State = 0;
int btPin39State = 0;
// declare game state variable
int gameState = 0;
void setup() {
// initialize Serial Comms for Debug (0) and BT(3)
Serial.begin(9600); //Sets the buad for Serial (debug port)
Serial3.begin(9600); //Sets the baud for Serial3 data transmission
// initialize all button pins as INPUTs
for (int x = 30; x <= 39; x++){
pinMode(x, INPUT);
}
// initialize LED pins as OUTPUTs:
for (int i = 44; i <= 53; i++){
pinMode(i, OUTPUT);
}
// lightup all LEDs
for (int j = 44; j <= 53; j++){
digitalWrite(j, HIGH);
delay(100);
}
// prompt device is ready
Serial.println("Device Ready");
}
void loop() {
// Read Data from Serial3 -- This is to get initial game status/command from app/bluetooth
if (Serial3.available() > 0) { // Send data only when you receive data:
data = Serial3.read();
// See what the command is
if (data == '1') {
Serial.write("Send it to GameOne");
Serial.write("\n");
gameOne();
}
// See what the command is
if (data == '2') {
Serial.write("Send it to GameTwo");
Serial.write("\n");
gameTwo();
}
if (data == '3') {
Serial.write("Send it to GameThree");
Serial.write("\n");
gameThree();
}
if (data == '4') {
Serial.write("Test");
Serial.write("\n");
}
}
btPin30State = digitalRead(btPin30);
btPin31State = digitalRead(btPin31);
btPin32State = digitalRead(btPin32);
btPin33State = digitalRead(btPin33);
btPin34State = digitalRead(btPin34);
btPin35State = digitalRead(btPin35);
btPin36State = digitalRead(btPin36);
btPin37State = digitalRead(btPin37);
btPin38State = digitalRead(btPin38);
btPin39State = digitalRead(btPin39);
// check if the pushbutton is pressed. If it is, the buttonState is HIGH:
if (btPin30State == HIGH) {
digitalWrite(ledPin44, HIGH);
tone(11, 1000, 500);
Serial.println("BTN 30 / LED 44");
gameOne();
} else {
digitalWrite(ledPin44, LOW);
}
if (btPin31State == HIGH) {
digitalWrite(ledPin45, HIGH);
Serial.println("BTN 31 / LED 45");
} else {
digitalWrite(ledPin45, LOW);
}
if (btPin32State == HIGH) {
digitalWrite(ledPin46, HIGH);
Serial.println("BTN 32 / LED 46");
} else {
digitalWrite(ledPin46, LOW);
}
if (btPin33State == HIGH) {
digitalWrite(ledPin47, HIGH);
Serial.println("BTN 33 / LED 47");
} else {
digitalWrite(ledPin47, LOW);
}
if (btPin34State == HIGH) {
digitalWrite(ledPin48, HIGH);
Serial.println("BTN 34 / LED 48");
} else {
digitalWrite(ledPin48, LOW);
}
if (btPin35State == HIGH) {
digitalWrite(ledPin49, HIGH);
Serial.println("BTN 35 / LED 49");
} else {
digitalWrite(ledPin49, LOW);
}
if (btPin36State == HIGH) {
digitalWrite(ledPin50, HIGH);
Serial.println("BTN 36 / LED 50");
} else {
digitalWrite(ledPin50, LOW);
}
if (btPin37State == HIGH) {
digitalWrite(ledPin51, HIGH);
Serial.println("BTN 37 / LED 51");
} else {
digitalWrite(ledPin51, LOW);
}
if (btPin38State == HIGH) {
digitalWrite(ledPin52, HIGH);
Serial.println("BTN 38 / LED 52");
} else {
digitalWrite(ledPin52, LOW);
}
if (btPin39State == HIGH) {
digitalWrite(ledPin53, HIGH);
Serial.println("BTN 39 / LED 53");
} else {
digitalWrite(ledPin53, LOW);
}
}
Сделанный. Смотрите основной пост, пожалуйста
Вам следует подумать об уменьшении размера кода за счет использования массивов и циклов for.
Немного посмотрев на это, я думаю, ваша проблема связана с тем, что gameState изменяется с 0 на 1 и никогда не возвращается обратно. Я предлагаю сделать набросок меньшего размера с одной или двумя родинками и работать с ним. единственный реальный способ отладки - это набор операторов печати.
Да, я работаю над уменьшенной / более чистой версией. Но суть проблемы, независимо от этого, заключается в моем фундаментальном понимании того, что происходит, когда вы переходите к функции вне основного цикла. После запуска game () возвращается в Main. Как мне ОСТАТЬСЯ В игре (), пока я не изменю свое состояние (например, игра не закончится)?
Непонятно, что должны делать ваши gameoneOne и gameOneTwo. Но если вы хотите, чтобы ваша функция выполнялась до тех пор, пока не изменится переменная состояния, почему бы вам не поместить тело функции в цикл while, который проверяет состояние?





Думаю, можно было бы структурировать это примерно так.
play_a_game:
for (some_number_of_times)
{
show_a_mole_and_let_them_wackit();
}
setup:
set up pins
say the game is starting
loop:
do
{
play_a_game();
}
while(game ending button not pressed and less then 10 moles have died);
say the game is over
У меня сейчас есть нечто очень похожее на это. Однако, когда кнопка нажата (переходит в высокий уровень), состояние do / while не меняется. Я НЕ использую прерывание ... но, судя по всему, в Arduino мне не должно быть этого. Любое понимание?
Вы также должны опубликовать свой main.