Игровая функция в Arduino

Я пытаюсь создать игру 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);
}




}

Вы также должны опубликовать свой main.

EvilTeach 07.12.2018 00:46

Сделанный. Смотрите основной пост, пожалуйста

frednikgohar 07.12.2018 01:13

Вам следует подумать об уменьшении размера кода за счет использования массивов и циклов for.

EvilTeach 07.12.2018 01:28

Немного посмотрев на это, я думаю, ваша проблема связана с тем, что gameState изменяется с 0 на 1 и никогда не возвращается обратно. Я предлагаю сделать набросок меньшего размера с одной или двумя родинками и работать с ним. единственный реальный способ отладки - это набор операторов печати.

EvilTeach 07.12.2018 01:42

Да, я работаю над уменьшенной / более чистой версией. Но суть проблемы, независимо от этого, заключается в моем фундаментальном понимании того, что происходит, когда вы переходите к функции вне основного цикла. После запуска game () возвращается в Main. Как мне ОСТАТЬСЯ В игре (), пока я не изменю свое состояние (например, игра не закончится)?

frednikgohar 07.12.2018 02:21

Непонятно, что должны делать ваши gameoneOne и gameOneTwo. Но если вы хотите, чтобы ваша функция выполнялась до тех пор, пока не изменится переменная состояния, почему бы вам не поместить тело функции в цикл while, который проверяет состояние?

Ari 07.12.2018 04:50
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
55
1

Ответы 1

Думаю, можно было бы структурировать это примерно так.

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 мне не должно быть этого. Любое понимание?

frednikgohar 08.12.2018 08:45

Другие вопросы по теме