Урок 49. Волк и яйца (Wolf and eggs) на Arduino

В этом уроке мы создадим игру «Волк и яйца». Эта игра сделана на основе электронной игры «Ну, погоди!», производимая с 1984 года, самая известная и популярная из серии первых советских портативных электронных игр. Сейчас она легко перебралась в компьютеры и телефоны, а появление сенсорных экранов и акселерометров в телефонах вводит новые правила управления.

Правила игры «Заяц волк»:

Во время игры с четырех сторон, поочерёдно, скатываются куриные яйца. Задача игрока ловить яйца в корзину, находящуюся в руках у волка (из мультфильма «Ну, погоди!»). Волк может принимать одно из четырёх положений, располагая корзину напротив мест скатывания яиц. За каждое пойманное яйцо игроку добавляется одно очко. Когда игрок пропускает яйцо, оно падает, разбивается и игра начинается заново.

Управление:

Как и в предыдущем уроке игрок управляет Волком используя не кнопки или джойстик, а акселерометр, присутствующий в Trema-модуле IMU 9 DOF (Inertial Measurement Unit 9 Degrees Of Freedom). Для того чтобы волк встал на против определенной линии нужно наклонить все устройство по диагонали к выбранной линии. Например для верхней левой линии необходимо наклонить все устройство влево и вверх одновременно.

Нам понадобится:

Для реализации проекта нам необходимо установить следующие библиотеки:

О том как устанавливать библиотеки, Вы можете ознакомиться на странице Wiki - Установка библиотек в Arduino IDE.

Видео:

Схема подключения:

Перед подключением модулей, закрепите винтами нейлоновые стойки в отверстиях секций 3 и 4 Trema Set Shield.

После чего закрепите установленные модули вкрутив через их отверстия нейлоновые винты в установленные ранее нейлоновые стойки (нейлоновые стойки и винты входят в комплектацию Trema Set Shield).

Наличие всего двух колодок в секциях Trema Set Shield, не позволит Вам неправильно установить модули, т.к. при неправильном подключении модули будут смещены относительно разметки своей секции и Вы не сможете закрепить их винтами.

Модули необязательно устанавливать в секции 3 или 4. Trema Set Shield распознает модули в любой из секций.

Код программы:

#include <iarduino_Position_BMX055.h>                                                 // Подключаем библиотеку iarduino_Position_BMX055 для работы с Trema-модулем IMU 9 DOF.
iarduino_Position_BMX055 sensor(BMA);                                                 // Создаём объект sensor указывая что ему требуется работать только с акселерометром.
#define BMX055_DISABLE_BMG                                                            // Не использовать гироскоп.
#define BMX055_DISABLE_BMM                                                            // Не использовать магнитометр.
#define MAX_VALUE   1.50                                                              // Максимальное значение по оси измерений.
#define MIN_VALUE  -1.50                                                              // Минимальное значение по оси измерений.
                                                                                      //
#include <iarduino_OLED.h>                                                            // Подключаем библиотеку iarduino_OLED.
iarduino_OLED myOLED(0x3C);                                                           // Объявляем объект myOLED, указывая адрес дисплея на шине I2C: 0x3C.
extern uint8_t MediumFontRus[];                                                       // Подключаем шрифт MediumFontRus.
extern uint8_t SmallFontRus[];                                                        // Подключаем шрифт SmallFontRus.
                                                                                      //
                      /* Объявляем массивы и переменные: */                           // Объявляем задействованные в игре рисунки в виде массива.
                                                                                      //
const uint8_t HandScare[] PROGMEM = { 45, 24,                                         // Поднятые руки волка.
0xC0, 0xE0, 0x38, 0xC8, 0x00, 0x70, 0x00, 0x80, 0x60, 0x20, 0xE0, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0x60, 0x20, 0xE0, 0x00, 0x80, 0x60, 0x10, 0xD0,   //
0x60, 0xC0, 0x00, 0x03, 0x06, 0x05, 0x0C, 0x08, 0x18, 0x30, 0x60, 0xC0, 0x9E, 0xF1,   //
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0x50, 0x1D, 0xC0, 0x60, 0x31, 0x10,   //
0x10, 0x11, 0x18, 0x0A, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x02, 0x06, 0x03, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x09, 0x06, 0x03, 0x01, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};                                //
                                                                                      //
const uint8_t EggBroken[] PROGMEM = { 23, 16,                                         // Разбитое яйцо.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0xC0, 0x80, 0x80, 0xE0, 0x70, 0x00, 0x80,   //
0x80, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x0B, 0x1F, 0x0E,   //
0x00, 0x24, 0x36, 0x7F, 0x6F, 0x39, 0x31, 0x53, 0x6F, 0x3B, 0x21, 0x00, 0x0C, 0x3E,   //
0x34, 0x1C, 0x00, 0x00};                                                              //
                                                                                      //
const uint8_t HandLeftUp[] PROGMEM = { 27, 24,                                        // Рука слева вверху.
0x00, 0x00, 0x00, 0x00, 0xF8, 0xFC, 0x0E, 0x06, 0x3E, 0xEE, 0x2C, 0xB8, 0x48, 0xC8,   //
0x88, 0x18, 0x70, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x60, 0xE0, 0xF0, 0xFB, 0xFF, 0x9E, 0x18, 0x3C, 0x7D, 0x7F, 0xFC, 0xC4, 0x07, 0x0F,   //
0xFC, 0xF8, 0xF1, 0x47, 0xBC, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x03, 0x07, 0x0F, 0x1C, 0x11, 0x11, 0x12, 0x10, 0x10, 0x18, 0x08, 0x08, 0x08,   //
0x19, 0x13, 0x12, 0x04, 0x28, 0x08, 0x38, 0x70, 0x60, 0x40, 0x00};                    //
                                                                                      //
const uint8_t HandLeftDown[] PROGMEM = { 26, 24,                                      // Рука слева внизу.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xF0, 0x18, 0xC8, 0x08, 0xCC, 0x84, 0xE4,   //
0xC4, 0x74, 0x5C, 0x4C, 0x4E, 0x6E, 0xEE, 0xE6, 0x74, 0x34, 0x10, 0x00, 0x00, 0xC0,   //
0xE0, 0xE0, 0xF0, 0xF0, 0xF0, 0xF5, 0xFF, 0xF1, 0xE1, 0xEF, 0xFE, 0xD4, 0xC0, 0xE0,   //
0x70, 0x3C, 0x0E, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x0F,   //
0x3F, 0x3F, 0x3F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3F, 0x3F, 0x3F, 0x1F, 0x0F, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};                                      //
                                                                                      //
const uint8_t HandRightUp[] PROGMEM = { 24, 24,                                       // Рука справа вверху.
0x00, 0x40, 0xC0, 0xE0, 0xE0, 0xB0, 0x90, 0x18, 0x08, 0x6C, 0xC4, 0xFC, 0x2C, 0x26,   //
0xFE, 0x0E, 0x3C, 0xF8, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x61, 0xF1, 0xFA, 0xFA, 0xFF, 0x3F, 0x1D, 0x3D, 0xFF, 0xFC, 0x7C, 0x3F,   //
0x3F, 0xFC, 0xFC, 0xFC, 0x78, 0x00, 0x00, 0x40, 0x60, 0x60, 0x70, 0x70, 0x70, 0x49,   //
0x4B, 0x6F, 0x67, 0x67, 0x60, 0x60, 0x61, 0x21, 0x20, 0x2A, 0x29, 0x1C, 0x07, 0x01,   //
0x00, 0x00};                                                                          //
                                                                                      //
const uint8_t HandRightDown[] PROGMEM = { 29, 24,                                     // Рука справа внизу.
0x00, 0x00, 0xCC, 0x9C, 0x9C, 0x3C, 0x28, 0x68, 0xC8, 0x8C, 0x0C, 0x04, 0x46, 0xE6,   //
0xEC, 0x7C, 0x4C, 0xDC, 0x7C, 0x38, 0xF0, 0xE0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x07, 0x0F, 0x3F, 0x76, 0xE4, 0x84, 0x19, 0x11, 0x33, 0x37,   //
0x3F, 0x1F, 0x19, 0xDF, 0xDF, 0x78, 0x78, 0xF8, 0xFF, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8,   //
0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1E, 0x18,   //
0x30, 0x30, 0x20, 0x68, 0x6A, 0x7A, 0x3B, 0x3D, 0x3F, 0x1F, 0x1F, 0x0F, 0x07, 0x03,   //
0x00, 0x00, 0x00};                                                                    //
                                                                                      //
const uint8_t WolfLeft[] PROGMEM = { 31, 48,                                          // Волк влево.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xF8, 0x1A, 0xDE, 0xF0,   //
0x7C, 0xFA, 0x7A, 0x7E, 0xFC, 0xF0, 0xFB, 0x9F, 0xC8, 0x36, 0x02, 0xC3, 0xFE, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xFF, 0x6F, 0xC7, 0x44, 0x44, 0x88,   //
0x94, 0xBF, 0x9A, 0xB2, 0xDE, 0xDA, 0x13, 0x1F, 0x01, 0xF3, 0xFF, 0xFF, 0xFE, 0xFF,   //
0x37, 0xE7, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x05,   //
0x05, 0x0B, 0x0B, 0x09, 0x85, 0xE4, 0x72, 0x3A, 0x0E, 0x02, 0x80, 0xE0, 0xF3, 0x3F,   //
0x3F, 0x07, 0x03, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x80, 0xE0, 0xE0, 0xF8, 0xFE, 0xFF, 0xFF, 0xFC, 0xFC, 0xFE, 0xFF, 0xC7,   //
0x41, 0x60, 0xA0, 0xA0, 0x70, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,   //
0x9C, 0x94, 0x16, 0x72, 0x6B, 0xFF, 0x9D, 0x98, 0x11, 0x11, 0x11, 0x11, 0x11, 0x1D,   //
0x1C, 0x18, 0x1C, 0x39, 0x2D, 0x26, 0xE6, 0x0C, 0x88, 0xD8, 0x30, 0x00, 0x00, 0x00,   //
0x00, 0x30, 0x38, 0x48, 0x59, 0xE9, 0xA9, 0xAA, 0xCA, 0xD4, 0xDD, 0xDB, 0xC2, 0x44,   //
0x48, 0x30, 0x00, 0x00, 0x00, 0x60, 0xF0, 0xFC, 0xEB, 0xC8, 0x5E, 0x57, 0x74, 0x2E,   //
0x3A, 0x1E, 0x0E, 0x04};                                                              //
                                                                                      //
const uint8_t WolfRight[] PROGMEM = { 27, 48,                                         // Волк вправо.
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x0E, 0x06, 0xEC, 0x18, 0xFE,   //
0xEC, 0xF0, 0xF0, 0xF8, 0xE8, 0xF0, 0xE0, 0xF0, 0x50, 0xD0, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x70, 0xFC, 0x37, 0xF7, 0xFE, 0xFE, 0xFF, 0xAF, 0x07, 0x3F,   //
0xA7, 0xB5, 0x7D, 0x4B, 0xEB, 0xBE, 0x44, 0x63, 0x20, 0x30, 0x78, 0xF0, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x17, 0x3F, 0xFF, 0xE3, 0x86, 0x00, 0x1C, 0x7D,   //
0xE7, 0xED, 0x1B, 0x36, 0x26, 0x2E, 0x3A, 0x1E, 0x0B, 0x06, 0x03, 0xF8, 0x30, 0xF0,   //
0x60, 0xFE, 0xC2, 0x66, 0xCC, 0xD8, 0xB0, 0xE0, 0xE7, 0xFF, 0xFE, 0xFC, 0xF8, 0xFF,   //
0xFF, 0xF8, 0xC0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x06, 0x1B,   //
0x34, 0x3A, 0x1E, 0x0F, 0x01, 0x07, 0x0D, 0x09, 0x10, 0x11, 0x11, 0x13, 0x13, 0x13,   //
0x39, 0xFB, 0xBF, 0x4C, 0x48, 0x50, 0x70, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,   //
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x78, 0x6C, 0x44, 0xD2, 0xDA, 0xDD, 0xD5,   //
0x54, 0x54, 0xF6, 0xE2, 0xA2, 0xE2, 0x41, 0x00};                                      //
                                                                                      //
                            /* Объявляем функции: */                                  //
                                                                                      //
void StartScreen();                                                                   // Функция заставки игры
void WolfMove();                                                                      // Функция движения волка.
void StartWolf();                                                                     // Функция вывода начального положения волка.
                                                                                      //
void EggMoveLeftUp();                                                                 // Функция движения яйца слева сверху.
void EggMoveLeftDown();                                                               // Функция движения яйца слева снизу.
void EggMoveRightUp();                                                                // Функция движения яйца справа сверху.
void EggMoveRightDown();                                                              // Функция движения яйца справа снизу.
                                                                                      //
void CatcheLeftUp();                                                                  // Функция проверки пойманного яйца слева сверху.
void CatcheLeftDown();                                                                // Функция проверки пойманного яйца слева снизу.
void CatcheRightUp();                                                                 // Функция проверки пойманного яйца справа сверху.
void CatcheRightDown();                                                               // Функция проверки пойманного яйца справа снизу.
                                                                                      //
void GenerationEggs();                                                                // Функция генерации яиц.
void EggsToCatch();                                                                   // Функция проверки пойманного яйца.
void Location();                                                                      // Функция прорисовки локации.
void ShowScore();                                                                     // Функция вывода очков.
void LevelComplicate();                                                               // Функция уровня сложности.
void GameOver();                                                                      // Функция завершения игры.
void Move();                                                                          // Функция отрисовки движения яиц.
                                                                                      //
                           /* Объявляем переменные: */                                //
                                                                                      //
int MassEggs[5];                                                                      // Массив в котором каждая переменная соответствует линии, с которой скатывается яйцо. 
                                                                                      //
int MassWolfPosition;                                                                 // Переменная положения волка
int eventWolf;                                                                        // Переменная события для волка.
int previousWolf;                                                                     // Переменная предыдущего положения волка.
int wolfPositionStart;                                                                // Переменная начального положения волка.
                                                                                      //
int eggsPosition;                                                                     // Переменная положения яйца.
int timeEggs;                                                                         // Переменная времени передвижения яиц.
int eventEggs;                                                                        // Переменная события для яиц.
int score;                                                                            // Переменная очков.
                                                                                      //
int s;                                                                                // Дополнительная переменная для генерации чисел.
int eventGenerationEggs;                                                              // Переменная события для генерации чисел.
                                                                                      //
int quantityScore;                                                                    // Количество очков.
                                                                                      //
const int levelComplicate1 = 6;                                                       // Константа уровня сложности 1.
const int levelComplicate2 = 3;                                                       // Константа уровня сложности 2.
const int levelComplicate3 = 2;                                                       // Константа уровня сложности 3.
const int levelComplicate4 = 1;                                                       // Константа уровня сложности 4.
                                                                                      //
int eggsLeftUp[7];                                                                    // Массив вывода картинки яйца на линию слева сверху.
int eggsLeftDown[7];                                                                  // Массив вывода картинки яйца на линию слева снизу.
int eggsRightUp[7];                                                                   // Массив вывода картинки яйца на линию справа сверху.
int eggsRightDown[7];                                                                 // Массив вывода картинки яйца на линию справа снизу.
                                                                                      //
uint32_t Tm;                                                                          // Переменная времени.
int eventStartGame;                                                                   // Переменная события для запуска игры.
                                                                                      //
void setup()                                                                          //
{                                                                                     //
                                                                                      //
  eggsLeftUp[1]    = 16;  eggsLeftUp[1]    <<= 8;  eggsLeftUp[1]    += 2;             // Координаты вывода яйца в зависимости шага.
  eggsLeftUp[2]    = 18;  eggsLeftUp[2]    <<= 8;  eggsLeftUp[2]    += 7;             //
  eggsLeftUp[3]    = 20;  eggsLeftUp[3]    <<= 8;  eggsLeftUp[3]    += 12;            //
  eggsLeftUp[4]    = 22;  eggsLeftUp[4]    <<= 8;  eggsLeftUp[4]    += 17;            //
  eggsLeftUp[5]    = 24;  eggsLeftUp[5]    <<= 8;  eggsLeftUp[5]    += 22;            //
  eggsLeftUp[6]    = 0;                                                               //
                                                                                      //
  eggsLeftDown[1]  = 36;  eggsLeftDown[1]  <<= 8;  eggsLeftDown[1]  += 2;             //
  eggsLeftDown[2]  = 38;  eggsLeftDown[2]  <<= 8;  eggsLeftDown[2]  += 7;             //
  eggsLeftDown[3]  = 40;  eggsLeftDown[3]  <<= 8;  eggsLeftDown[3]  += 12;            //
  eggsLeftDown[4]  = 42;  eggsLeftDown[4]  <<= 8;  eggsLeftDown[4]  += 17;            //
  eggsLeftDown[5]  = 44;  eggsLeftDown[5]  <<= 8;  eggsLeftDown[5]  += 22;            //
  eggsLeftDown[6]  = 0;                                                               //
                                                                                      //
  eggsRightUp[1]   = 16;  eggsRightUp[1]   <<= 8;  eggsRightUp[1]   += 125;           //
  eggsRightUp[2]   = 18;  eggsRightUp[2]   <<= 8;  eggsRightUp[2]   += 120;           //
  eggsRightUp[3]   = 20;  eggsRightUp[3]   <<= 8;  eggsRightUp[3]   += 115;           //
  eggsRightUp[4]   = 22;  eggsRightUp[4]   <<= 8;  eggsRightUp[4]   += 110;           //
  eggsRightUp[5]   = 24;  eggsRightUp[5]   <<= 8;  eggsRightUp[5]   += 105;           //
  eggsRightUp[6]   = 0;                                                               //
                                                                                      //
  eggsRightDown[1] = 36;  eggsRightDown[1] <<= 8;  eggsRightDown[1] += 125;           //
  eggsRightDown[2] = 38;  eggsRightDown[2] <<= 8;  eggsRightDown[2] += 120;           //
  eggsRightDown[3] = 40;  eggsRightDown[3] <<= 8;  eggsRightDown[3] += 115;           //
  eggsRightDown[4] = 42;  eggsRightDown[4] <<= 8;  eggsRightDown[4] += 110;           //
  eggsRightDown[5] = 44;  eggsRightDown[5] <<= 8;  eggsRightDown[5] += 105;           //
  eggsRightDown[6] = 0;                                                               //
                                                                                      //
  myOLED.begin();                                                                     // Инициируем работу с дисплеем.
  myOLED.invScr(true);                                                                // Инвертируем цвет дисплея.
  myOLED.bgImage(false);                                                              // В дальнейшем выводить изображения без фона.
                                                                                      //
  while(!Serial){}                                                                    // Ждём готовность Serial к передаче данных в монитор последовательного порта.
  sensor.begin(true);                                                                 // Инициируем работу с датчиками объекта sensor.
                                                                                      //
  Serial.begin(9600);                                                                 // открывает последовательный порт, устанавливает скорость 9600 бит/c
  randomSeed(analogRead(0));                                                          // Инициализируем генератор псевдослучайных чисел и выбираем считывание с аналогового входа.
                                                                                      //
  eventStartGame = 1;                                                                 // Разрешаем начало игры.
}                                                                                     //
                                                                                      //
void loop()                                                                           //
{                                                                                     //
  if (eventStartGame)                                                                 // Если игра разрешена, то настраиваем начальные параметры
  {                                                                                   //
    myOLED.autoUpdate(false);                                                         // Запрещаем автоматический вывод данных. Информация на дисплее будет обновляться только после обращения к функции update().
    StartScreen();                                                                    // Показываем заставку.
    StartWolf();                                                                      // Выводим начальное положение волка.
    ShowScore();                                                                      // Выводим очки.
    Location();                                                                       // Прорисовываем локацию.
    GenerationEggs();                                                                 // Генерируем начальную линию с которой будет скатываться яйцо.
    eventStartGame = 0;                                                               // Запрещаем начало игры.
  }                                                                                   //
                                                                                      //
  WolfMove();                                                                         // Изменяем положение волка.
  LevelComplicate();                                                                  // Выбираем уровня сложности.
                                                                                      //
  if (millis()-Tm>500)                                                                // Функция будет работать каждые 500 мс.
  {                                                                                   //
    Tm  = millis();                                                                   // Сохраняем значение millis().
    eventEggs = 1;                                                                    // Приравниваем переменную события к единице.
    MassEggs[1] <<= 1;                                                                // Постоянно сдвигаем бит в элементе массива слева сверху.
    MassEggs[2] <<= 1;                                                                // Постоянно сдвигаем бит в элементе массива слева снизу.
    MassEggs[3] <<= 1;                                                                // Постоянно сдвигаем бит в элементе массива справа сверху.
    MassEggs[4] <<= 1;                                                                // Постоянно сдвигаем бит в элементе массива справа снизу.
                                                                                      //
    if (eventGenerationEggs)                                                          // Разрешаем генерацию нового яйца.
    {                                                                                 //
      GenerationEggs();                                                               // Функция генерации яйца.
      eventGenerationEggs = 0;                                                        // Если сгенерировалось яйцо, запрещаем событие.
    }                                                                                 //
  }                                                                                   //
                                                                                      //  
  Move();                                                                             // Отрисовываем движение яиц.
                                                                                      //
  if (eventEggs) {myOLED.update(); eventEggs = 0;}                                    // Выводим на экран, если яйцо скатилось вниз на один шаг.
  if (eventWolf) {myOLED.update(); eventWolf = 0;}                                    // Выводим на экран, если изменилось положение волка.
                                                                                      //
}                                                                                     //
                                                                                      //
void Move()                                                                           // Функция отрисовки движения яиц.
{                                                                                     //
  EggMoveLeftUp();                                                                    // Функция движение и отрисовки яйца по линии слева сверху.
  EggMoveLeftDown();                                                                  // Функция движение и отрисовки яйца по линии слева снизу.
  EggMoveRightUp();                                                                   // Функция движение и отрисовки яйца по линии справа сверху.
  EggMoveRightDown();                                                                 // Функция движение и отрисовки яйца по линии справа снизу.
}                                                                                     //
                                                                                      //
void GenerationEggs()                                                                 // Функция генерации яиц.
{                                                                                     //
  do{s=random(1, 5);}                                                                 // Сравниваем предыдущее значение и новое сгенерированное. 
  while(s==eggsPosition);                                                             // Выполняем цикл пока оба значение равны друг другу.
  eggsPosition = s;                                                                   // Присваиваем новое значение.
  switch (eggsPosition)                                                               // Выбираем позицию яйца.
  {                                                                                   //
    case 1:                                                                           // Позиция яйца слева сверху.
    MassEggs[1] |= 1;                                                                 // Задаем новое яйцо слева сверху.
    break;                                                                            // Выходим из оператора case.
                                                                                      //
    case 2:                                                                           // Позиция яйца слева снизу.
    MassEggs[2] |= 1;                                                                 // Задаем новое яйцо слева снизу.
    break;                                                                            // Выходим из оператора case.
                                                                                      //
    case 3:                                                                           // Позиция яйца справа сверху.
    MassEggs[3] |= 1;                                                                 // Задаем новое яйцо справа сверху.
    break;                                                                            // Выходим из оператора case.
                                                                                      //
    case 4:                                                                           // Позиция яйца справа снизу.
    MassEggs[4] |= 1;                                                                 // Задаем новое яйцо справа снизу.
    break;                                                                            // Выходим из оператора case.
  }                                                                                   //
}                                                                                     //
                                                                                      //
void EggMoveLeftUp()                                                                  // Функция движение и отрисовки яйца по линии слева сверху.
{                                                                                     //
  if (bitRead(MassEggs[1],quantityScore)){eventGenerationEggs = 1;}                   // Разрешаем генерацию нового яйца в зависимости от уровня сложности.
  if (bitRead(MassEggs[1],6)){CatcheLeftUp();}                                        // Проверяем поймал волк яйцо.
  for (int i = 1; i <= 5; i++)                                                        // Отрисовываем новый массив с помощью цикла.
  {                                                                                   //
    if (bitRead(MassEggs[1],i))                                                       // Если бит равен единице, то выводим положение яйца на экране.
    {                                                                                 //
      myOLED.drawCircle(lowByte(eggsLeftUp[i-1]),highByte(eggsLeftUp[i-1]),3,false,0);// Гасим предыдущее положение яйца в соответствии с координатами.
      myOLED.drawCircle(lowByte(eggsLeftUp[i]),  highByte(eggsLeftUp[i]),  3,false,1);// Выводим на экран положение яйца в соответствии с координатами.
    }                                                                                 //
  }                                                                                   //
}                                                                                     //
                                                                                      //
void EggMoveLeftDown()                                                                // Функция движение и отрисовки яйца по линии слева снизу.
{                                                                                     //
  if (bitRead(MassEggs[2],quantityScore)){eventGenerationEggs = 1;}                   // Разрешаем генерацию нового яйца в зависимости от уровня сложности.
  if (bitRead(MassEggs[2],6)){CatcheLeftDown();}                                      // Проверяем поймал волк яйцо.
  for (int i = 1; i <= 5; i++)                                                        // Отрисовываем новый массив с помощью цикла.
  {                                                                                   //
    if (bitRead(MassEggs[2],i))                                                       // Если бит равен единице, то выводим положение яйца на экране.
    {                                                                                 //
  myOLED.drawCircle(lowByte(eggsLeftDown[i-1]),highByte(eggsLeftDown[i-1]),3,false,0);// Гасим предыдущее положение яйца в соответствии с координатами.
  myOLED.drawCircle(lowByte(eggsLeftDown[i]),  highByte(eggsLeftDown[i]),  3,false,1);// Выводим на экран положение яйца в соответствии с координатами.
    }                                                                                 //
  }                                                                                   //
}                                                                                     //
                                                                                      //
void EggMoveRightUp()                                                                 // Функция движение и отрисовки яйца по линии справа сверху.
{                                                                                     //
  if (bitRead(MassEggs[3],quantityScore)){eventGenerationEggs = 1;}                   // Разрешаем генерацию нового яйца в зависимости от уровня сложности.
  if (bitRead(MassEggs[3],6)){CatcheRightUp();}                                       // Проверяем поймал волк яйцо.
  for (int i = 1; i <= 5; i++)                                                        // Отрисовываем новый массив с помощью цикла.
  {                                                                                   //
    if (bitRead(MassEggs[3],i))                                                       // Если бит равен единице, то выводим положение яйца на экране.
    {                                                                                 //
    myOLED.drawCircle(lowByte(eggsRightUp[i-1]),highByte(eggsRightUp[i-1]),3,false,0);// Гасим предыдущее положение яйца в соответствии с координатами.
    myOLED.drawCircle(lowByte(eggsRightUp[i]),  highByte(eggsRightUp[i]),  3,false,1);// Выводим на экран положение яйца в соответствии с координатами.
    }                                                                                 //
  }                                                                                   //
}                                                                                     //
                                                                                      //
void EggMoveRightDown()                                                               // Функция движение и отрисовки яйца по линии справа сверху.
{                                                                                     //
  if (bitRead(MassEggs[4],quantityScore)){eventGenerationEggs = 1;}                   // Разрешаем генерацию нового яйца в зависимости от уровня сложности.
  if (bitRead(MassEggs[4],6)){CatcheRightDown();}                                     // Проверяем поймал волк яйцо.
  for (int i = 1; i <= 5; i++)                                                        // Отрисовываем новый массив с помощью цикла.
  {                                                                                   //
    if (bitRead(MassEggs[4],i))                                                       // Если бит равен единице, то выводим положение яйца на экране.
    {                                                                                 //
myOLED.drawCircle(lowByte(eggsRightDown[i-1]),highByte(eggsRightDown[i-1]),3,false,0);// Гасим предыдущее положение яйца в соответствии с координатами.
myOLED.drawCircle(lowByte(eggsRightDown[i]),  highByte(eggsRightDown[i]),  3,false,1);// Выводим на экран положение яйца в соответствии с координатами.
    }                                                                                 //
  }                                                                                   //
}                                                                                     //
                                                                                      //
void LevelComplicate()                                                                // Функция выбора уровня сложности
{                                                                                     //
  if (!score)     {quantityScore = levelComplicate1;}                                 // Если счет равен 0, то уровень сложности 1.
  if (score == 5) {quantityScore = levelComplicate2;}                                 // Если счет равен 5, то уровень сложности 2.
  if (score == 10){quantityScore = levelComplicate3;}                                 // Если счет равен 10, то уровень сложности 3.
  if (score == 15){quantityScore = levelComplicate4;}                                 // Если счет равен 15, то уровень сложности 4.
}                                                                                     //
                                                                                      //
void EggsToCatch()                                                                    // Функция когда яйцо поймано.
{                                                                                     //
  score++;                                                                            // Увеличиваем количество очков.
  ShowScore();                                                                        // Выводим счет.
}                                                                                     //
                                                                                      //
void CatcheLeftUp()                                                                   // Функция проверки пойманного яйца слева сверху.
{                                                                                     //
  if (bitRead(MassWolfPosition,1) && bitRead(MassEggs[1],6))                          // Положение волка должно совпадать с положением яйца.
  {                                                                                   //
    bitClear(MassEggs[1],6);                                                          // Очищаем бит положения яйца.
    myOLED.drawCircle (22, 24, 3, false, 0);                                          // Очищаем последнее положение яйца.
    EggsToCatch();                                                                    // Если яйцо поймано, то переходим к функции когда яйцо поймано.
  }                                                                                   //
  else                                                                                // Если яйцо не поймано, выводим анимацию проигрыша, количество очков и начинаем игру заново.
  {                                                                                   //
    myOLED.autoUpdate(true);                                                          // Разрешаем автоматический вывод данных.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения волка.
    myOLED.drawImage(HandScare,  40, 42, IMG_ROM);                                    // Выводим на экран картинку поднятых рук.
    myOLED.drawImage(WolfLeft,  46, 64, IMG_ROM);                                     // Выводим на экран волка направленного в сторону разбившегося яйца.
    myOLED.drawCircle (22, 24, 3, false, 0);                                          // Очищаем последнее положение яйца.
    myOLED.drawCircle (32, 31, 3, false, 1);                                          // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (32, 31, 3, false, 0);                                          // Очищаем последнее положение яйца.
    myOLED.drawCircle (32, 41, 3, false, 1);                                          // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (32, 41, 3, false, 0);                                          // Очищаем последнее положение яйца.
    myOLED.drawCircle (32, 51, 3, false, 1);                                          // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (32, 51, 3, false, 0);                                          // Очищаем последнее положение яйца.
    myOLED.drawImage(EggBroken,  24, 63, IMG_ROM);                                    // Выводим картинку разбившегося яйца.
    delay(2000);                                                                      // Задержка 2 с.
    GameOver();                                                                       // Иначе завершение игры.
  }                                                                                   //
}                                                                                     //
                                                                                      //
void CatcheLeftDown()                                                                 // Функция проверки пойманного яйца слева снизу.
{                                                                                     //
  if (bitRead(MassWolfPosition,2) && bitRead(MassEggs[2],6))                          // Положение волка должно совпадать с положением яйца.
  {                                                                                   //
    bitClear(MassEggs[2],6);                                                          // Очищаем бит положения яйца.
    myOLED.drawCircle (22, 44, 3, false, 0);                                          // Очищаем последнее положение яйца.
    EggsToCatch();                                                                    // Если яйцо поймано, то переходим к функции когда яйцо поймано.
  }                                                                                   //
  else                                                                                // Если яйцо не поймано, выводим анимацию проигрыша, количество очков и начинаем игру заново.
  {                                                                                   //
    myOLED.autoUpdate(true);                                                          // Разрешаем автоматический вывод данных.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения волка.
    myOLED.drawImage(HandScare,  40, 42, IMG_ROM);                                    // Выводим на экран картинку руки подняты вверх.
    myOLED.drawImage(WolfLeft,  46, 64, IMG_ROM);                                     // Выводим на экран волка направленного в сторону разбившегося яйца.
    myOLED.drawCircle (22, 44, 3, false, 0);                                          // Очищаем последнее положение яйца. 
    myOLED.drawCircle (32, 51, 3, false, 1);                                          // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (32, 51, 3, false, 0);                                          // Очищаем последнее положение яйца.
    myOLED.drawImage(EggBroken,  24, 63, IMG_ROM);                                    // Выводим картинку разбившегося яйца.
    delay(2000);                                                                      // Задержка 2 с.
    GameOver();                                                                       // Иначе завершение игры.
  }                                                                                   //
}                                                                                     //
                                                                                      //    
void CatcheRightUp()                                                                  // Функция проверки пойманного яйца справа сверху.
{                                                                                     //
  if (bitRead(MassWolfPosition,3) && bitRead(MassEggs[3],6))                          // Положение волка должно совпадать с положением яйца.
  {                                                                                   //
    bitClear(MassEggs[3],6);                                                          // Очищаем бит положения яйца.
    myOLED.drawCircle (105, 24, 3, false, 0);                                         // Очищаем последнее положение яйца.
    EggsToCatch();                                                                    // Если яйцо поймано, то переходим к функции когда яйцо поймано.
  }                                                                                   //
  else                                                                                // Если яйцо не поймано, выводим анимацию проигрыша, количество очков и начинаем игру заново.
  {                                                                                   //
    myOLED.autoUpdate(true);                                                          // Разрешаем автоматический вывод данных.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения волка.
    myOLED.drawImage(HandScare,  42, 42, IMG_ROM);                                    // Выводим на экран картинку поднятых рук.
    myOLED.drawImage(WolfRight, 48, 64, IMG_ROM);                                     // Выводим на экран волка направленного в сторону разбившегося яйца.
    myOLED.drawCircle (105, 24, 3, false, 0);                                         // Очищаем последнее положение яйца.
    myOLED.drawCircle (95,  31, 3, false, 1);                                         // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (95,  31, 3, false, 0);                                         // Очищаем последнее положение яйца.
    myOLED.drawCircle (95,  41, 3, false, 1);                                         // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (95,  41, 3, false, 0);                                         // Очищаем последнее положение яйца.
    myOLED.drawCircle (95,  51, 3, false, 1);                                         // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (95,  51, 3, false, 0);                                         // Очищаем последнее положение яйца.
    myOLED.drawImage(EggBroken,  87, 63, IMG_ROM);                                    // Выводим картинку разбившегося яйца.
    delay(2000);                                                                      // Задержка 2 с.
    GameOver();                                                                       // Иначе завершение игры.
  }                                                                                   //
}                                                                                     //
                                                                                      //
void CatcheRightDown()                                                                // Функция проверки пойманного яйца справа снизу.
{                                                                                     //
  if (bitRead(MassWolfPosition,4) && bitRead(MassEggs[4],6))                          // Положение волка должно совпадать с положением яйца.
  {                                                                                   //
    bitClear(MassEggs[4],6);                                                          // Очищаем бит положения яйца.
    myOLED.drawCircle (105, 44, 3, false, 0);                                         // Очищаем последнее положение яйца.
    EggsToCatch();                                                                    // Если яйцо поймано, то переходим к функции когда яйцо поймано.
  }                                                                                   //
  else                                                                                // Если яйцо не поймано, выводим анимацию проигрыша, количество очков и начинаем игру заново.
  {                                                                                   //
    myOLED.autoUpdate(true);                                                          // Разрешаем автоматический вывод данных.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения волка.
    myOLED.drawImage(HandScare,  42, 42, IMG_ROM);                                    // Выводим на экран картинку поднятых рук.
    myOLED.drawImage(WolfRight, 48, 64, IMG_ROM);                                     // Выводим на экран волка направленного в сторону разбившегося яйца.
    myOLED.drawCircle (105, 44, 3, false, 0);                                         // Очищаем последнее положение яйца.
    myOLED.drawCircle (95,  51, 3, false, 1);                                         // Двигаем яйцо вниз.
    delay(450);                                                                       // Задержка 450 мс.
    myOLED.drawCircle (95, 51, 3, false, 0);                                          // Очищаем последнее положение яйца. 
    myOLED.drawImage(EggBroken,  87, 63, IMG_ROM);                                    // Выводим картинку разбившегося яйца.
    delay(2000);                                                                      // Задержка 2 с.
    GameOver();                                                                       // Иначе завершение игры.
  }                                                                                   //
}                                                                                     //
                                                                                      //
void WolfMove(){                                                                      // Функция движения волка.
  sensor.read();                                                                      // Читаем данные датчика (акселерометра).
  previousWolf = MassWolfPosition;                                                    // Запоминаем последнее положение волка.
                                                                                      //
  if (sensor.axisX <= -0.5 && sensor.axisY >=  0.5)                                   // Сравниваем показания датчика направления влево - вверх. Выводим на экран новое положение волка с корзинкой.
  {                                                                                   //
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfLeft,   46, 64, IMG_ROM);                                    // Выводим на экран новое положение волка.
    myOLED.drawImage(HandLeftUp, 27, 43, IMG_ROM);                                    // Выводим на экран новое корзинки.
    MassWolfPosition = 0;                                                             // Очищаем переменную позиций.
    bitSet(MassWolfPosition,1);                                                       // Устанавливаем бит нового положения волка.
  }                                                                                   //
                                                                                      //
  if (sensor.axisX <= -0.5 && sensor.axisY <= -0.5)                                   // Сравниваем показания датчика направления влево - вниз. Выводим на экран новое положение волка с корзинкой.
  {                                                                                   //
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfLeft,     46, 64, IMG_ROM);                                  // Выводим на экран новое положение волка.
    myOLED.drawImage(HandLeftDown, 27, 64, IMG_ROM);                                  // Выводим на экран новое корзинки.
    MassWolfPosition = 0;                                                             // Очищаем переменную позиций.
    bitSet(MassWolfPosition,2);                                                       // Устанавливаем бит нового положения волка.
  }                                                                                   //
                                                                                      //
  if (sensor.axisX >=  0.5 && sensor.axisY >=  0.5)                                   // Сравниваем показания датчика направления вправо - вверх. Выводим на экран новое положение волка с корзинкой.
  {                                                                                   //
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfRight,   48, 64, IMG_ROM);                                   // Выводим на экран новое положение волка.
    myOLED.drawImage(HandRightUp, 72, 43, IMG_ROM);                                   // Выводим на экран новое корзинки.
    MassWolfPosition = 0;                                                             // Очищаем переменную позиций.
    bitSet(MassWolfPosition,3);                                                       // Устанавливаем бит нового положения волка.
  }                                                                                   //
                                                                                      //
  if (sensor.axisX >=  0.5 && sensor.axisY <= -0.5)                                   // Сравниваем показания датчика направления вправо - вниз. Выводим на экран новое положение волка с корзинкой.
  {                                                                                   //
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfRight,     48, 64, IMG_ROM);                                 // Выводим на экран новое положение волка.
    myOLED.drawImage(HandRightDown, 72, 64, IMG_ROM);                                 // Выводим на экран новое корзинки.
    MassWolfPosition = 0;                                                             // Очищаем переменную позиций.
    bitSet(MassWolfPosition,4);                                                       // Устанавливаем бит нового положения волка.
  }                                                                                   //
                                                                                      //
  if (previousWolf != MassWolfPosition){eventWolf = 1;}                               // Если волк изменил свое положение присваиваем переменной события единицу.
}                                                                                     //
                                                                                      //
void StartWolf()                                                                      // Функция вывода начального положения волка.
{                                                                                     //
  wolfPositionStart = random(1, 5);                                                   // Генерируем случайное положение для волка.
  switch (wolfPositionStart)                                                          // В зависимости от положения волка, выводим соответствующий рисунок.
  {                                                                                   //
    case 1:                                                                           // Положение слева вверх.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfLeft,  46, 64, IMG_ROM);                                     // Выводим на экран новое положение волка.
    myOLED.drawImage(HandLeftUp,    27, 43, IMG_ROM);                                 // Выводим на экран новое корзинки.
    bitSet(MassWolfPosition,1);                                                       // Устанавливаем бит нового положения волка.
    break;                                                                            // Выходим из оператора case.
    case 2:                                                                           // Положение слева вниз.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfLeft,  46, 64, IMG_ROM);                                     // Выводим на экран новое положение волка.
    myOLED.drawImage(HandLeftDown,  27, 64, IMG_ROM);                                 // Выводим на экран новое корзинки.
    bitSet(MassWolfPosition,2);                                                       // Устанавливаем бит нового положения волка.
    break;                                                                            // Выходим из оператора case.
    case 3:                                                                           // Положение справа вверх.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfRight, 48, 64, IMG_ROM);                                     // Выводим на экран новое положение волка.
    myOLED.drawImage(HandRightUp,   72, 43, IMG_ROM);                                 // Выводим на экран новое корзинки.
    bitSet(MassWolfPosition,3);                                                       // Устанавливаем бит нового положения волка.
    break;                                                                            // Выходим из оператора case.
    case 4:                                                                           // Положение справа вниз.
    myOLED.drawRect(27, 16, 100, 64, true, 0);                                        // Очищаем место изменения положения волка и корзинки.
    myOLED.drawImage(WolfRight, 48, 64, IMG_ROM);                                     // Выводим на экран новое положение волка.
    myOLED.drawImage(HandRightDown, 72, 64, IMG_ROM);                                 // Выводим на экран новое корзинки.
    bitSet(MassWolfPosition,4);                                                       // Устанавливаем бит нового положения волка.
    break;                                                                            // Выходим из оператора case.
  }                                                                                   //
}                                                                                     //
                                                                                      //
void Location(){                                                                      // Функция прорисивки локации.
  myOLED.drawLine   (0, 20, 24, 29, 1);                                               // Выводим на экран полочку для яиц слева сверху.
  myOLED.drawLine   (0, 21, 24, 30, 1);                                               //
  myOLED.drawLine   (0, 22, 24, 31, 1);                                               //
                                                                                      //
  myOLED.drawLine   (0, 40, 24, 49, 1);                                               // Выводим на экран полочку для яиц слева снизу.
  myOLED.drawLine   (0, 41, 24, 50, 1);                                               //
  myOLED.drawLine   (0, 42, 24, 51, 1);                                               //
                                                                                      //
  myOLED.drawLine   (103, 29, 127, 20, 1);                                            // Выводим на экран полочку для яиц справа сверху.
  myOLED.drawLine   (103, 30, 127, 21, 1);                                            //
  myOLED.drawLine   (103, 31, 127, 22, 1);                                            //
                                                                                      //
  myOLED.drawLine   (103, 49, 127, 40, 1);                                            // Выводим на экран полочку для яиц справа снизу.
  myOLED.drawLine   (103, 50, 127, 41, 1);                                            //
  myOLED.drawLine   (103, 51, 127, 42, 1);                                            //
}                                                                                     //
                                                                                      //
void ShowScore(){                                                                     // Функция вывода очков.
  myOLED.setFont(SmallFontRus);                                                       // Указываем шрифт который требуется использовать для вывода цифр и текста.
  myOLED.print(score, OLED_C, 10);                                                    // Выводим количество очков по центру 10 строки.
  myOLED.update();                                                                    // Разрешаем автоматический вывод данных.
}                                                                                     //
                                                                                      //
void GameOver()                                                                       // Функция завершения игры.
{                                                                                     //
  MassEggs[1] = 0;                                                                    // Очищаем элемент массива слева сверху.
  MassEggs[2] = 0;                                                                    // Очищаем элемент массива слева снизу.
  MassEggs[3] = 0;                                                                    // Очищаем элемент массива справа сверху.
  MassEggs[4] = 0;                                                                    // Очищаем элемент массива справа снизу.                                                                                  
  eventGenerationEggs = 0;                                                            //
                                                                                      //
  MassWolfPosition = 0;                                                               // Переменная положения волка
  eventWolf = 0;                                                                      // Переменная события для волка.
  previousWolf = 0;                                                                   // Переменная предыдущего положения волка.
  wolfPositionStart = 0;                                                              // Переменная начального положения волка.
  eggsPosition = 0;                                                                   // Переменная положения яйца.
  timeEggs = 0;                                                                       // Переменная времени передвижения яиц.
  eventEggs = 0;                                                                      // Переменная события для яиц.
  s = 0;                                                                              // Дополнительная переменная для генерации чисел.
  quantityScore = 0;                                                                  // Количество очков.
                                                                                      //
  myOLED.clrScr();                                                                    // Чистим экран.
  myOLED.setFont(SmallFontRus);                                                       // Указываем шрифт который требуется использовать для вывода цифр и текста.
  myOLED.print(F("Игра окончена"), OLED_C, 25);                                       // Выводим текст по центру 25 строки.
  myOLED.print(F("Очки - "), 35, 40);                                                 // Выводим текст 35 столбца 40 строки.
  myOLED.print(score, 80, 40);                                                        // Выводим количество очков 80 столбца 40 строки.
  myOLED.update();                                                                    // Разрешаем автоматический вывод данных.
  delay(2000);                                                                        // Задержка 2 секунды.
  myOLED.clrScr();                                                                    // Чистим экран.
                                                                                      //
score = 0;                                                                            // Обнуляем очки.
eventStartGame = 1;                                                                   // Разрешаем начало игры.
}                                                                                     //
                                                                                      //
void StartScreen(){                                                                   // Функция вывода заставки игры.
  myOLED.drawRect (0, 0, 127, 63, false, 1);                                          // Прорисовываем рамку игрового поля.
  myOLED.setFont(MediumFontRus);                                                      // Указываем шрифт который требуется использовать для вывода цифр и текста.
  myOLED.print(F("ЗАЯЦ ВОЛК"), OLED_C, 40);                                           // Выводим текст по центру 50 строки.
  myOLED.update();                                                                    // Разрешаем автоматический вывод данных.
  delay(2000);                                                                        // Задержка 2 секунды.
  myOLED.clrScr();                                                                    // Чистим экран.
                                                                                      //
  myOLED.drawRect (0, 0, 127, 63, false, 1);                                          // Прорисовываем рамку игрового поля.
  myOLED.print(F("От"), OLED_C, 25);                                                  // Выводим текст по центру 20 строки.
  myOLED.print(F("IARDUINO"), OLED_C, 50);                                            // Выводим текст по центру 20 строки.
  myOLED.update();                                                                    // Разрешаем автоматический вывод данных.
  delay (2000);                                                                       // Задержка 2 секунды.
  myOLED.clrScr();                                                                    // Чистим экран.
  }                                                                                   //

Алгоритм работы:

  • В начале скетча (до кода setup) выполняются следующие действия:
    • Подключаем библиотеку iarduino_Position_BMX055 для работы с датчиком Trema IMU 9 DOF.
    • Объявляем объект sensor, указывая работу только с акселерометром.
    • Подключаем графическую библиотеку iarduino_OLED для работы с Trema OLED дисплеем.
    • Объявляем объект myOLED указывая адрес дисплея на шине I2C, он должен совпадать с адресом установленным переключателем на обратной стороне платы OLED дисплея.
    • Подключаем шрифты предустановленные в библиотеке myOLED.
    • Объявляем двумерный массивы для задействованных картинок (Положение волка, положение рук волка, разбитое яйцо) и переменные участвующие в работе скетча.
    • Объявляем функции используемые в скетче.
  • В коде setup выполняются следующие действия:
    • Объявляем координаты положения яиц, необходимые, чтобы выводить яйцо на линии в соответствии с его движением.
    • Инициируем работу с Trema OLED дисплеем, инвертируем цвет дисплея, разрешаем вывод изображения без фона.
    • Инициируем работу с датчиком Trema IMU 9 DOF.
    • Подключаем генерирование случайных чисел с помощью аналогового входа.
    • Разрешаем начало игры.
  • В коде loop выполняются следующие действия:
    • При разрешенном флаге "начала игры", определяем начальные параметры игры (Запрещаем автоматический вывод данных, выводим на экран заставку игры (функция "StartScreen()"), выбираем начальное положение волка (функция "StartWolf()"), выводим на экран количество очков (функция "ShowScore()"), отрисовываем локацию (функция "Location()"), выбираем начальную линию с которой будет катиться яйцо (функция "GenerationEggs()"), запрещаем начало игры.
    • Осуществляется движение волка (функция "WolfMove()"). В ней фиксируется предыдущее положение волка и новое, а затем сравниваются положения. Если изменилось положение волка, то выводим на экран. Это сделано, для экономии памяти. Так же считываются данные полученные с акселерометра и в зависимости от наклона на экран выводится соответствующее положение волка на против нужной линии. В зависимости от положения волка в переменой "MassWolfPosition" устанавливается бит. Влево-вверх - бит 1 устанавливается в единицу, влево-вниз - бит 2 устанавливается в единицу, вправо-вверх - бит 3 устанавливается в единицу, вправо-вниз - бит 4 устанавливается в единицу.
    • Функция выбора уровня, (функция "LevelComplicate()"). С увеличением количества очков, увеличивается уровень сложности.
    • Каждые 500 мс сдвигаем производим сдвиг влево для каждого элемента массива и генерируем новое яйцо, если событие разрешено.
    • Функция отрисовки движения яйца (функция "Move()"). В ней 4 функции (функция "EggMoveLeftUp()" или "EggMoveLeftDown()" или "EggMoveRightUp()" или "EggMoveRightDown()"), каждая из которых отвечает за свою линию. В них мы разрешаем генерацию нового яйца, в зависимости от уровня сложности (чем больше уровень, тем быстрее генерируются яйца). Так же проверка поимки волком яйца, для этого, как только яйцо достигает края линии, обращаемся к функции "CatcheLeftUp()" или "CatcheLeftDown()" или "CatcheRightUp()" или "CatcheRightDown()", в которых проверяем позицию волка и яйца. Если они совпадают, то игра продолжается, сбрасываем задействованные переменные для конкретной линии и переходим к функции, когда волк поймал яйцо (функция "EggsToCatch()"). В ней увеличиваем очки, выводим их на экран. Если волк не поймал яйцо, то игра заканчивается, выводим анимацию проигрыша и переходим к функции завершения игры (функция "GameOver()"), сбрасываются все очки и переменные, разрешаем начало игры и возвращаемся в начало.
    • Проверка совершения движения яйца и волка. При совершении движения, выводится новое положения яйца и волка.

Ссылки:

Обсуждение