Оглавление:

Arduino - Плитки для фортепиано: 16 шагов (с изображениями)
Arduino - Плитки для фортепиано: 16 шагов (с изображениями)

Видео: Arduino - Плитки для фортепиано: 16 шагов (с изображениями)

Видео: Arduino - Плитки для фортепиано: 16 шагов (с изображениями)
Видео: Свидание в 16 vs 26 лет 😨😳 2024, Ноябрь
Anonim
Arduino - Плитка для фортепиано
Arduino - Плитка для фортепиано

Привет, интернет-пользователи! Речь пойдет о том, как сделать то, что ОПРЕДЕЛЕННО не является копией мобильной игры на arduino uno r3.

Итак, для начала вам понадобятся все следующие детали! 1x Arduino Uno r3 (42 доллара США)

2x LCD Keypad Shield (19 долларов США каждая)

5 кнопок

5 резисторов 220 Ом

28x проводов

Хорошо, когда у вас есть все части, пора начинать!

Шаг 1. Подключение

Проводка
Проводка
Проводка
Проводка
Проводка
Проводка

Начните с подключения вашего Arduino и друзей, как показано на схеме, Убедитесь, что кнопки подключены правильно, со слотами A0-4 на нижней стороне направляющих для кнопок, иначе Arduino будет думать, что кнопки удерживаются постоянно, а не только при нажатии.

Шаг 2: Заявления

Весь код здесь должен идти до настройки void и цикла void, потому что все эти переменные и объекты используются в некоторых функциях, которые мы будем настраивать.

Начните с добавления:

#включают

в верхней части вашего кода это говорит arduino использовать библиотеку «LiquidCrystal.h» и функции, которые являются ее частью.

Следующий шаг - определить контакты, которые мы используем для наших кнопок, поместив этот код ниже нашего #include:

#define btnEnter A0 # define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

Мы определяем термины от btnEnter и от btn1 до btn 4, чтобы нам было легче читать код, или изменить при необходимости. Это означает, что когда мы набираем btn1, arduino будет знать, что мы на самом деле имеем в виду кнопку 15. Хотя мы вызываем порты port 15, 16, 17 и 18, они обозначены на Arduino как A1, A2, A3 и A4, потому что это порты, используемые специально для аналоговых входов, хотя мы используем их только для цифровых входов.

Далее мы собираемся создать объекты, которые будут управлять жидкокристаллическими дисплеями. Для этого поместите этот код под наши определения

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight (2, 3, 4, 5, 6, 7);

Это сообщает Arduino, что когда мы вызываем lcdLeft или lcdRight, мы ссылаемся на объект LiquidCrystal. Цифры в прикрепленных скобках сообщают Arduino, какие порты объект должен использовать для отправки сообщений на ЖК-дисплей, когда мы используем их функции.

Теперь нам нужно объявить переменные, поместив следующий фрагмент кода под объявлениями объекта:

// эти переменные являются параметрами, которые вы можете изменить - более высокие числа = более высокая скорость игры int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// устанавливаем переменные для gameboolean bolPlay; // отслеживает, если игрок int intScore; // отслеживает счет игрока int intDiff; // просто эстетическая вещь, чтобы сказать, на какой сложности игра // настраиваем переменные для input int intEnter; // отслеживает, нажимает ли пользователь кнопку ввода int intInput; // отслеживает, какие кнопки нажимает пользователь boolean bolTilePressed; // убедитесь, что игрок случайно не нажмет кнопку 5 раз и не проиграет // установить переменные для поворота int intTick; // считает миллионы (за цикл) до intDelay int intDelay; // время ожидания программой следующего поворота в миллисекундах int intGameSpeed; // отсутствие параметров отладки boolean bolSerialBoard; // при истине распечатает плату в серийном мониторе

Мы объявляем переменную, указывая тип данных, а затем имя переменной, например. int thisIsAnInteger

Логические переменные, такие как bolSerialBoard и bolPlay, могут иметь только одно из двух значений: true или false.

Целочисленная переменная (int), такая как intScore и intInput, может принимать в качестве значений целые числа, например 1, 5 или 100.

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

Каждая из переменных здесь используется программой в нескольких разных местах, вот краткое описание того, что делает каждая из них.

bolPlay сообщает программе, должно ли отображаться меню или должна быть запущена сама игра.

intScore отслеживает счет игрока, когда он попадает в плитки, intDiff используется в главном меню, чтобы сообщить программе, какой бит текста печатать на ЖК-дисплее, intEnter используется, чтобы сообщить программе, нажата ли кнопка ввода (крайняя левая), intInput используется, чтобы сообщить программе, какая из остальных 4 кнопок нажата.

bolTilePressed используется, чтобы убедиться, что программа читает только при нажатии кнопки, а не при ее удерживании.

intGameSpeed, intGameSpeedEasy, intGameSpeedMedium и intGameSpeedHard используются для управления скоростью ускорения игры в зависимости от выбранной сложности.

intTick и intDelay используются, чтобы программа не двигала доску каждый раз, когда она зацикливается.

bolSerialBoard используется, чтобы вы могли заставить программу отправлять плату на последовательный монитор Arduino в виде ряда чисел для целей тестирования.

Наконец, пришло время объявить нашу доску как массив, используя этот код:

// настраиваем массив игры int arrGame [16] [4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

Массив - это матрица, любая точка которой может быть вызвана для математических вычислений или может быть изменена.

Теперь ваш код должен выглядеть примерно так:

// включаем библиотеки # включаем

// эти переменные - это параметры, которые вы можете изменить - большее число = более быстрое ускорение игры

int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// Определить контакты

#define btnEnter A0 #define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

// создание ЖК-объектов (n, ~, n, ~, ~, n)

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight (2, 3, 4, 5, 6, 7);

// настраиваем игровой массив

int arrGame [16] [4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

// устанавливаем переменные для игры

boolean bolPlay; // отслеживает, если игрок int intScore; // отслеживает счет игрока int intDiff; // просто эстетическая вещь, чтобы сказать, на какой сложности игра

// настраиваем переменные для ввода

int intEnter; // отслеживает, нажимает ли пользователь кнопку ввода int intInput; // отслеживает, какие кнопки нажимает пользователь boolean bolTilePressed; // убедитесь, что игрок случайно не нажмет кнопку 5 раз и не проиграет

// устанавливаем переменные для поворота

int intTick; // считает миллионы (за цикл) до intDelay int intDelay; // время ожидания программой следующего поворота в миллисекундах int intGameSpeed;

// отсутствие параметров отладки

boolean bolSerialBoard; // при истине распечатает плату в серийном мониторе

Шаг 3: Функция настройки

Цикл настройки - это функция, которую Arduino считывает только один раз при первом запуске.

В цикле настройки мы просто устанавливаем значения нескольких наших переменных, потому что вместо того, чтобы устанавливать им значение при их объявлении, мы делаем это здесь.

Начните с помещения этого кода в вашу настройку Void.

bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium;

Каждая строка просто устанавливает значение переменной.

bolPlay имеет значение false, чтобы игра не запускалась.

intScore установлен на 0, потому что, естественно, ваш счет начинается с 0.

intTick начинается с 0, потому что в данный момент программа ничего не считает.

intDelay установлен в 1000, потому что это скорость, с которой начинаются плитки.

intDiff - это просто аскетическая штука, чтобы программа знала, что писать для сложности игры.

intGameSpeed установлен на любое значение intGameSpeedMedium, что означает, что он установлен на средней сложности.

Затем поместите этот код в Void Setup под кодом, который вы только что ввели.

lcdLeft.begin (16, 2); lcdRight.begin (16, 2);

Serial.begin (9600);

Это сообщает Arduino о необходимости начать связь с компьютером через последовательный монитор (отображается при нажатии кнопки в правом верхнем углу IDE Arduino).

Ваш Void Setup теперь должен выглядеть примерно так!

void setup () {Serial.begin (9600); // запускаем серийный монитор // устанавливаем переменные bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; // начало ЖК-дисплея lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

Шаг 4: функция цикла

Функция цикла запускается Arduino на каждой итерации Arduino.

Скопируйте следующий код в Void Loop.

void loop () {input (); // проверяем воспроизведение ввода if (bolPlay == true) {if (intTick> = intDelay) {// проверяем, должна ли игра сыграть ход или продолжать ждать Serial.println ("~~~~~~~ ~~ "); // печатаем, чтобы обозначить движение доски // writeSerial (); // если опция включена, записываем плату в серийные кнопки Game (); // проверяем входы игрока playBoard (); // перемещаем доску и добавляем новую плитку clearLcd (); // очистка ЖК-дисплеев перед рисованием drawBoard (); // рисуем плату на lcd bottomCheck (); intTick = 0; // сбрасываем intTick} else {buttonsGame (); // проверяем входы игрока clearLcd (); // очистка ЖК-дисплеев перед рисованием drawBoard (); // рисуем плату на ЖК-дисплее intTick = intTick + intGameSpeed; // добавляем в галочку}} else {clearLcd (); // очистка ЖК-дисплеев перед рисованием title (); // отображение заголовка и информации о счете. buttonsMenu (); // читаем проигрыватель input clearBoard (); // обеспечить всю доску = 0} delay (10); // задерживаем Arduino на короткое время}

когда bolPlay равен true, это означает, что игра идет, и должен быть запущен весь код для того, чтобы игра игралась, но мы хотим, чтобы доска только добавляла новую плитку и двигалась вниз, когда intTick больше, чем наш intDelay, в противном случае мы по-прежнему хотим разрешить пользователю нажимать кнопку для нажатия на плитку, а для intTick - увеличивать скорость.

Большая часть этого кода использует функции, которые нам еще предстоит создать, и мы создадим их на следующих этапах. Назначение этих функций заключается в следующем.

Ввод читает, какие кнопки нажал пользователь.

buttonsGame контролирует действия кнопок в игре, а не в меню

playBoard добавляет новую плитку на доску, а затем перемещает все на доске на одну клетку вниз

clearLCD очищает ЖК-дисплеи, чтобы убедиться, что за плиткой не осталось призраков

drawBoard проходит через arrGame и распечатывает его на ЖК-дисплеях

clearBoard очищает всю arrGame, когда игра не находится в игре

bottomCheck проверяет нижнюю часть arrGame на наличие сбоя

title отображает название игры и информацию о счете, когда находится в меню

Меню кнопок управляет действиями пользователя, вводимыми в меню.

gameOver - еще одна функция, хотя здесь не вызывается, так как вместо этого вызывается в функциях bottomCheck и buttonsGame.

Шаг 5: Функция ClearLCD

чтобы создать функцию, мы начинаем с добавления этого в код

void functionName () {

}

"functionName" может быть любым, если оно еще не существует.

Скопируйте этот код в свою программу:

void clearLcd () {для (int i = 0; i <= 15; i ++) {для (int ii = 0; ii <= 1; ii ++) {lcdLeft.setCursor (i, ii); lcdLeft.write (""); lcdRight.setCursor (i, ii); lcdRight.write (""); }}}

это проходит через весь массив, используя 2 счетных цикла, чтобы пройти через каждую точку на ЖК-дисплее и записать пробел.

Без сброса на ничто ЖК-дисплей будет поддерживать все, что было написано ранее.

Шаг 6: функция DrawBoard

скопируйте этот код в свою программу

void drawBoard () {for (int i = 1; i <= 15; i ++) {// рисуем столбцы 1 и 2 на левом ЖК-дисплее // если тайл = 0 ничего не пишем, = 1 пишем "#", = 2 напишите "@" lcdLeft.setCursor (i, 1); // устанавливается в первый столбец (крайний левый) if (arrGame [0] == 1) {lcdLeft.write ("#");} if (arrGame [0] == 2) {lcdLeft.write ("@");} lcdLeft.setCursor (i, 0); // установить второй столбец (в центре слева) if (arrGame [1] == 1) {lcdLeft.write ("#");} if (arrGame [1] == 2) {lcdLeft.write ("@");} lcdRight.setCursor (i, 1); // устанавливается в третий столбец (в центре справа) if (arrGame [2] == 1) {lcdRight.write ("#");} if (arrGame [2] == 2) {lcdRight.write ("@");} lcdRight.setCursor (i, 0); // установить четвертый столбец (крайний правый) if (arrGame [3] == 1) {lcdRight.write ("#");} if (arrGame [3] == 2) {lcdRight.записывать("@");} } }

при этом используется цикл для прохождения каждой строки платы, затем он проверяет, равен ли какой-либо столбец в строке 1 или 2, в зависимости от этого он затем печатает на ЖК-дисплее хэштег для плитки, которая еще не была попадание или @ для плитки попадания.

Шаг 7: функция PlayBoard

скопируйте этот код в свою программу.

void playBoard () {for (int i = 0; i <= 3; i ++) {arrGame [0] = 0;} // очищаем верхнюю строку arrGame [0] [random (0, 4)] = 1; // устанавливаем случайную точку в верхней строке как плитку для (int i = 15; i> = 1; i -) {// работаем снизу доски вверх для (int ii = 0; ii <= 3; ii ++) {// для каждого столбца arrGame [ii] = arrGame [i - 1] [ii]; }}}

этот код начинается с очистки всей верхней строки до 0 или отсутствия плитки, а затем устанавливает для одной случайной плитки значение 1 и отключает плитку.

Затем он проходит счетный цикл в обратном порядке, от 15 до 1, устанавливая строку равной тому, чему равна строка над ней, заставляя плату перемещаться вниз по ЖК-дисплею.

Шаг 8: функция ClearBoard

скопируйте этот код в свою программу.

void clearBoard () {// сбросить значения тика и задержки intTick = 0; intDelay = 1000; // просматриваем доску и устанавливаем все на 0 for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {arrGame [ii] = 0; }}}

Этот код запускается, когда игра не играет, чтобы убедиться, что для всей arrGame установлено значение 0 или нет тайлов, с помощью счетных циклов для прохождения массива.

Код также сбрасывает значения intDelay и intTick.

Шаг 9: функция заголовка

скопируйте следующий код в свою программу

void title () {// записываем заголовок на ЖК-дисплей и пробел для оценки lcdRight.setCursor (0, 0); lcdRight.write («Плитки пианино»); lcdRight.setCursor (0, 1); lcdRight.write ("Оценка:"); // преобразовываем счет в строку char strScore [3]; sprintf (strScore, "% d", intScore); // отображение счета на ЖК-дисплее lcdRight.write (strScore); // добавляем сложность lcdRight.setCursor (10, 1); если (intDiff == 0) {lcdRight.write ("Легко"); } если (intDiff == 1) {lcdRight.write ("Средний"); } если (intDiff == 2) {lcdRight.write ("Жесткий"); } // Нажимаем немного инструкции lcdLeft.setCursor (0, 0); lcdLeft.write («Нажмите Enter»); lcdLeft.setCursor (0, 1); lcdLeft.write («начать!»); }

Этот код записывает название игры и счет на ЖК-дисплеи, он делает это, сообщая ЖК-дисплею, где начать ввод с помощью LCD.setCursor, а затем записывает строку в LCD.write.

Здесь также создается новая переменная strScore, она используется для преобразования intScore в строковый или символьный тип данных с помощью функции sprintf.

Здесь также используется intDiff, на основе его значений он распечатывает различные варианты сложности.

Шаг 10: Функция ButtonsMenu

вставьте следующий код в свою программу

void buttonsMenu () {// при нажатии клавиши Enter запускается игра и сбрасывается значение счета if (intEnter == 1) {bolPlay = true; intScore = 0; playBoard (); drawBoard (); } // при нажатии кнопки 3 включаем опцию отладки последовательной печати платы if (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active"); bolSerialBoard = true; } else {Serial.println ("Последовательная плата отключена"); bolSerialBoard = false; }} // устанавливаем легкую сложность для скорости игры if (intInput == 0) {Serial.print ("Игра установлена на easy ("); Serial.print (intGameSpeedEasy); Serial.println ("ms ускорение)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // устанавливаем скорость игры на среднюю сложность if (intInput == 1) {Serial.print ("Игра установлена на среднюю ("); Serial.print (intGameSpeedMedium); Serial.println ("мс ускорение)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // устанавливаем жесткую скорость игры if (intInput == 2) {Serial.print ("Игра установлена на жесткую ("); Serial.print (intGameSpeedHard); Serial.println ("ms ускорение)"); intDiff = 2; intGameSpeed = intGameSpeedHard; }}

этот код запускается только тогда, когда bolPlay равен false в цикле void

если intEnter установлен в 1, это означает, что была нажата кнопка ввода, если она нажата, программа устанавливает для bolPlay значение true и игра запускается.

Затем программа считывает, чему равен intInput. если он равен 0, нажимается первая слева кнопка, переходя вправо до 3. Если intInput равно 4, никакая кнопка не нажимается.

при нажатии кнопок 0-2 игра изменяет сложность, а также регулирует значение скорости игры, что означает, что она будет ускоряться быстрее.

при нажатии кнопки 3 игра активирует или деактивирует режим отладки, при котором вся плата печатается на последовательном мониторе, чтобы помочь в поиске проблем в программе.

Шаг 11: функция ButtonsGame

скопируйте следующий код в свою программу

void buttonsGame () {if (intInput! = 4) {// если кнопка нажата if (bolTilePressed == false) {// только если bolTilePressed - ложное действие триггера для проверки нажатия кнопки bolTilePressed = true; // затем установите для bolTilePressed значение true, чтобы убедиться, что он снова не срабатывает по умолчанию int intLowestTile = 0; // устанавливается на плитку с наименьшей плиткой int intCheckedTile = 15; // отслеживать, какие плитки были проверены while (intLowestTile == 0) {// пока ничего не установлено, проверять плитки для (int i = 0; i 100) {// до тех пор, пока int задержка не ниже 100 intDelay = intDelay - 20; // берем из него значение}} else {Serial.println ("Нажата неверная кнопка"); игра закончена(); // в противном случае игра окончена}}}}}

Код запускается только тогда, когда bolPlay равен true в цикле void.

Как и buttonsMenu, на основе значения intInput он проверяет, попал ли игрок в плитку или пропустил ее.

Это делается путем прохождения arrGame снизу вверх, используя цикл while, чтобы найти, какая строка является самой низкой с тайлом unhit. Затем он проверяет, является ли место в этой строке, соответствующее нажатой кнопке, незащищенной плиткой или нет, если она не нажата, она устанавливает ее равной 2 вместо 1, что означает, что она будет отображаться как @, в противном случае запускается gameOver. функция, которую нам еще предстоит создать.

Эта функция также использует переменную bolTilePressed, задав ей значение true, когда кнопка нажата, и false, когда кнопка не нажата. Это сделано для того, чтобы пользователь случайно не проиграл игру, потому что программа думала, что он нажимал кнопку несколько раз, когда они ее удерживали.

Шаг 12: функция GameOver

Скопируйте следующий код в свою программу

void gameOver () {Serial.println ("Игра окончена!"); Serial.print («Ваша оценка:»); Serial.println (intScore); Serial.print («Ваша скорость была:»); Serial.println (intDelay); bolPlay = false; }

Это запускается функциями checkBottom или buttonGame и запускает конец игры, устанавливая для bolPlay значение false.

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

Шаг 13: функция ввода

Скопируйте следующий код в свою программу.

void input () {intEnter = digitalRead (btnEnter); // читать ввод // читать, какой из других входов, или если ни один из них не установлен в 4 if (digitalRead (btn1) == HIGH) {intInput = 0;} else {if (digitalRead (btn2) == HIGH) {intInput = 1;} else {if (digitalRead (btn3) == HIGH) {intInput = 2;} else {if (digitalRead (btn4) == HIGH) {intInput = 3;} else {intInput = 4; }}}} // серийная печать входов if (intEnter == 1) {Serial.println ("Enter Pressed!");} if (intInput! = 4) {Serial.print ("Button Press:"); Serial.println (intInput); } else {// если никакая кнопка не нажата, сбросить bolTilePressed bolTilePressed = false; }}

Этот код используется с функциями buttonsGame и buttonsMenu. на основе кнопок, нажатых пользователем, он устанавливает значение intInput, или, если кнопка не нажата, устанавливает intInput равным 4.

Если никакая кнопка не нажата, это то место, где bolTilePressed сбрасывается для функции buttonsGame.

Он также выводит сообщение на монитор последовательного порта, на котором была нажата кнопка.

Шаг 14: функция BottomCheck

скопируйте следующий код в свою программу.

void bottomCheck () {for (int i = 0; i <= 3; i ++) {// для 4 столбцов if (arrGame [15] == 1) {// если плитка находится внизу Serial.println («Плитка внизу»); arrGame [15] = 2; drawBoard (); задержка (400); arrGame [15] = 1; drawBoard (); задержка (400); arrGame [15] = 2; drawBoard (); задержка (400); arrGame [15] = 1; drawBoard (); задержка (400); игра закончена(); }}}

используя цикл, этот код проверяет нижнюю строку arrGame на наличие каких-либо незащищенных тайлов (тайлы равны 1), если в нижней части экрана есть незащищенный тайл, он мигает тайлом, а затем запускает функцию завершения игры.

Шаг 15: функция WriteSerial

скопируйте следующий код в свою программу

void writeSerial () {if (bolSerialBoard == true) {for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {Serial.print (arrGame [ii]); Serial.print (","); } Serial.println (""); }}}

Это функция, за которой следует опция отладки, которую можно включить в функции buttonsMenu. Если для bolSerialBoard установлено значение true в этой функции, он пройдет через arrGame и распечатает всю плату в последовательном мониторе для целей тестирования с использованием массива.

Шаг 16: Завершение

Завершение!
Завершение!

Весь ваш код не должен быть полным и выглядеть примерно так!

/ * * Имя - Плитки пианино; Arduino * Автор - Доменик Марулли * Дата - 11 / *

/ включить библиотеки

#включают

// эти переменные - это параметры, которые вы можете изменить - большее число = более быстрое ускорение игры

int intGameSpeedEasy = 10; int intGameSpeedMedium = 25; int intGameSpeedHard = 80;

// Определить контакты

#define btnEnter A0 #define btn1 15 #define btn2 16 #define btn3 17 #define btn4 18

// создание ЖК-объектов (n, ~, n, ~, ~, n)

LiquidCrystal lcdLeft (8, 9, 12, 10, 11, 13); LiquidCrystal lcdRight (2, 3, 4, 5, 6, 7);

// настраиваем игровой массив

int arrGame [16] [4] = {{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};

// устанавливаем переменные для игры

boolean bolPlay; // отслеживает, если игрок int intScore; // отслеживает счет игрока int intDiff; // просто эстетическая вещь, чтобы сказать, на какой сложности игра

// настраиваем переменные для ввода

int intEnter; // отслеживает, нажимает ли пользователь кнопку ввода int intInput; // отслеживает, какие кнопки нажимает пользователь boolean bolTilePressed; // убедитесь, что игрок случайно не нажмет кнопку 5 раз и не проиграет

// устанавливаем переменные для поворота

int intTick; // считает миллионы (за цикл) до intDelay int intDelay; // время ожидания программой следующего поворота в миллисекундах int intGameSpeed;

// отсутствие параметров отладки

boolean bolSerialBoard; // при истине распечатает плату в серийном мониторе

// установка, которая будет запущена один раз

void setup () {Serial.begin (9600); // запускаем серийный монитор // устанавливаем переменные bolPlay = false; intScore = 0; intTick = 0; intDelay = 1000; intDiff = 1; intGameSpeed = intGameSpeedMedium; // начало ЖК-дисплея lcdLeft.begin (16, 2); lcdRight.begin (16, 2); }

// цикл, который будет выполняться каждые 10 миллисекунд

void loop () {input (); // проверяем воспроизведение ввода if (bolPlay == true) {if (intTick> = intDelay) {// проверяем, должна ли игра сыграть ход или продолжать ждать Serial.println ("~~~~~~~ ~~ "); // печатаем, чтобы обозначить движение доски // writeSerial (); // если опция включена, записываем плату в серийные кнопки Game (); // проверяем входы игрока playBoard (); // перемещаем доску и добавляем новую плитку clearLcd (); // очистка ЖК-дисплеев перед рисованием drawBoard (); // рисуем плату на lcd bottomCheck (); intTick = 0; // сбрасываем intTick} else {buttonsGame (); // проверяем входы игрока clearLcd (); // очистка ЖК-дисплеев перед рисованием drawBoard (); // рисуем плату на ЖК-дисплее intTick = intTick + intGameSpeed; // добавляем в галочку}} else {clearLcd (); // очистка ЖК-дисплеев перед рисованием title (); // отображение заголовка и информации о счете. buttonsMenu (); // читаем проигрыватель input clearBoard (); // обеспечить всю доску = 0} delay (10); // задерживаем Arduino на короткое время}

// очищает ЖК-дисплей, чтобы не осталось незанятых ячеек

void clearLcd () {для (int i = 0; i <= 15; i ++) {для (int ii = 0; ii <= 1; ii ++) {lcdLeft.setCursor (i, ii); lcdLeft.write (""); lcdRight.setCursor (i, ii); lcdRight.write (""); }}}

// рисует плату на ЖК-дисплее

void drawBoard () {for (int i = 1; i <= 15; i ++) {// рисуем столбцы 1 и 2 на левом ЖК-дисплее // если тайл = 0 ничего не пишем, = 1 пишем "#", = 2 напишите "@" lcdLeft.setCursor (i, 1); // устанавливается в первый столбец (крайний левый) if (arrGame [0] == 1) {lcdLeft.write ("#");} if (arrGame [0] == 2) {lcdLeft.write ("@");} lcdLeft.setCursor (i, 0); // установить второй столбец (в центре слева) if (arrGame [1] == 1) {lcdLeft.write ("#");} if (arrGame [1] == 2) {lcdLeft.write ("@");} lcdRight.setCursor (i, 1); // устанавливается в третий столбец (в центре справа) if (arrGame [2] == 1) {lcdRight.write ("#");} if (arrGame [2] == 2) {lcdRight.write ("@");} lcdRight.setCursor (i, 0); // установить четвертый столбец (крайний правый) if (arrGame [3] == 1) {lcdRight.write ("#");} if (arrGame [3] == 2) {lcdRight.записывать("@");} } }

// перемещает доску вниз и помещает случайное значение в качестве плитки

void playBoard () {for (int i = 0; i <= 3; i ++) {arrGame [0] = 0;} // очищаем верхнюю строку arrGame [0] [random (0, 4)] = 1; // устанавливаем случайную точку в верхней строке как плитку для (int i = 15; i> = 1; i -) {// работаем снизу доски вверх для (int ii = 0; ii <= 3; ii ++) {// для каждого столбца arrGame [ii] = arrGame [i - 1] [ii]; }}}

// устанавливает всю доску в 0 и сбрасывает переменные на предварительную игру

void clearBoard () {// сбросить значения тика и задержки intTick = 0; intDelay = 1000; // просматриваем доску и устанавливаем все на 0 for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {arrGame [ii] = 0; }}}

// отображает главное меню на ЖК-дисплее

void title () {// записываем заголовок на ЖК-дисплей и пробел для оценки lcdRight.setCursor (0, 0); lcdRight.write («Плитки пианино»); lcdRight.setCursor (0, 1); lcdRight.write ("Оценка:"); // преобразовываем счет в строку char strScore [3]; sprintf (strScore, "% d", intScore); // отображение счета на ЖК-дисплее lcdRight.write (strScore); // добавляем сложность lcdRight.setCursor (10, 1); если (intDiff == 0) {lcdRight.write ("Легко"); } если (intDiff == 1) {lcdRight.write ("Средний"); } если (intDiff == 2) {lcdRight.write ("Жесткий"); } // Нажимаем немного инструкции lcdLeft.setCursor (0, 0); lcdLeft.write («Нажмите Enter»); lcdLeft.setCursor (0, 1); lcdLeft.write («начать!»); }

// проверяет кнопки и что с ними делать вне игры

void buttonsMenu () {// при нажатии клавиши Enter запускается игра и сбрасывается значение счета if (intEnter == 1) {bolPlay = true; intScore = 0; playBoard (); drawBoard (); } // при нажатии кнопки 3 включаем опцию отладки последовательной печати платы if (intInput == 3) {if (bolSerialBoard == false) {Serial.println ("Serial Board Active"); bolSerialBoard = true; } else {Serial.println ("Последовательная плата отключена"); bolSerialBoard = false; }} // устанавливаем легкую сложность для скорости игры if (intInput == 0) {Serial.print ("Игра установлена на easy ("); Serial.print (intGameSpeedEasy); Serial.println ("ms ускорение)"); intDiff = 0; intGameSpeed = intGameSpeedEasy; } // устанавливаем скорость игры на среднюю сложность if (intInput == 1) {Serial.print ("Игра установлена на среднюю ("); Serial.print (intGameSpeedMedium); Serial.println ("мс ускорение)"); intDiff = 1; intGameSpeed = intGameSpeedMedium; } // устанавливаем жесткую скорость игры if (intInput == 2) {Serial.print ("Игра установлена на жесткую ("); Serial.print (intGameSpeedHard); Serial.println ("ms ускорение)"); intDiff = 2; intGameSpeed = intGameSpeedHard; }}

// проверяем кнопки и что с ними делать в игре

void buttonsGame () {if (intInput! = 4) {// если кнопка нажата if (bolTilePressed == false) {// только если bolTilePressed - ложное действие триггера для проверки нажатия кнопки bolTilePressed = true; // затем установите для bolTilePressed значение true, чтобы убедиться, что он снова не срабатывает по умолчанию int intLowestTile = 0; // устанавливается на плитку с наименьшей плиткой int intCheckedTile = 15; // отслеживать, какие плитки были проверены while (intLowestTile == 0) {// пока ничего не установлено, проверять плитки для (int i = 0; i 100) {// до тех пор, пока int задержка не ниже 100 intDelay = intDelay - 20; // берем из него значение}} else {Serial.println ("Нажата неверная кнопка"); игра закончена(); // в противном случае игра окончена}}}}}

void gameOver () {

Serial.println («Игра окончена!»); Serial.print («Ваш результат был:»); Serial.println (intScore); Serial.print ("Ваша скорость была:"); Serial.println (intDelay); bolPlay = false; }

// проверяет ввод игрока

void input () {intEnter = digitalRead (btnEnter); // читать ввод // читать, какой из других входов, или если ни один из них не установлен в 4 if (digitalRead (btn1) == HIGH) {intInput = 0;} else {if (digitalRead (btn2) == HIGH) {intInput = 1;} else {if (digitalRead (btn3) == HIGH) {intInput = 2;} else {if (digitalRead (btn4) == HIGH) {intInput = 3;} else {intInput = 4; }}}} // серийная печать входов if (intEnter == 1) {Serial.println ("Enter Pressed!");} if (intInput! = 4) {Serial.print ("Button Press:"); Serial.println (intInput); } else {// если никакая кнопка не нажата, сбросить bolTilePressed bolTilePressed = false; }}

// проверяем нижнюю часть платы на предмет отказа

void bottomCheck () {for (int i = 0; i <= 3; i ++) {// для 4 столбцов if (arrGame [15] == 1) {// если плитка находится внизу Serial.println («Плитка внизу»); arrGame [15] = 2; drawBoard (); задержка (400); arrGame [15] = 1; drawBoard (); задержка (400); arrGame [15] = 2; drawBoard (); задержка (400); arrGame [15] = 1; drawBoard (); задержка (400); игра закончена(); }}}

// выводит плату в серийный монитор, если bolSerialBoard истинно

void writeSerial () {if (bolSerialBoard == true) {for (int i = 0; i <= 15; i ++) {for (int ii = 0; ii <= 3; ii ++) {Serial.print (arrGame [ii]); Serial.print (","); } Serial.println (""); }}}

После того, как весь код введен, загрузите его на свой ардуино и наслаждайтесь!

Рекомендуемые: