3 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Делаем Тетрис на Arduino

Урок 47. Игра тетрис на Arduino

В этом уроке мы создадим игру «Тетрис». Это известная многим игра «головоломка» изобретённая и написанная советским программистом Алексеем Пажитновым. Первоначальная версия игры была написана для компьютера «Электроника-60» на языке Паскаль. Игра была выпущена 6 июня 1984 г. Мировую известность игра приобрела благодаря её выпуску на портативной консоли GameBoy компании Nintendo

Правила игры «Тетрис»:

Вверху игрового поля появляются случайные геометрические фигуры, которые падают пока не достигнут низа поля или других фигур. Во время падения, фигуры можно сдвигать по горизонтали (влево / вправо), поворачивать на 90° (по часовой стрелке) и ускорять их падение. Таким образом игрок может выбирать место падения фигуры. Если из упавших фигур соберётся горизонтальный ряд без пробелов (пустот), то этот ряд исчезнет, а всё что было над ним опустится. За каждый исчезнувший ряд игрок получает очки. Скорость падения фигур увеличивается с каждым новым уровнем игры. Уровень игры увеличивается через определённое количество появившихся фигур. Игра заканчивается если новая фигура не может появиться вверху игрового поля по причине того что ей мешают уже имеющиеся там фигуры.

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

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

  • Arduino Uno х 1шт.
  • Trema OLED-дисплей 128×64 х 1шт.
  • Trema-модуль Кнопка х 4шт. (в ассортименте: синяя, красная, зелёная)
  • Trema Set Shield х 1шт.
    И никаких проводов (кроме USB для загрузки скетча).

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

  • iarduino_OLED — графическая библиотека для работы с Trema OLED дисплеями.

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

Видео:

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

  • Перед подключением модулей, закрепите винтами нейлоновые стойки в отверстиях секций 1, 2, 3, 5 и 6 Trema Set Shield.
  • Установите Trema Set Shield на Arduino Uno .

Остальные модули устанавливаются на Trema Set Shield следующим образом: Trema Кнопки устанавливаются в центр нижних колодок секций 1, 2, 5 и 6, а Trema OLED-дисплей 128×64 устанавливается в верхнюю колодку 3 секции, как это показано на рисунках ниже.

  • Устанавливаем Trema-модуль Кнопку в 1 посадочную площадку.
  • Устанавливаем Trema-модуль Кнопку в 2 посадочную площадку.
  • Устанавливаем Trema OLED-дисплей 128×64 в 3 посадочную площадку, в верхнюю I2C колодоку.
  • Устанавливаем Trema-модуль Кнопку в 5 посадочную площадку.
  • Устанавливаем Trema-модуль Кнопку в 6 посадочную площадку.
  • Полученный результат представлен на рисунке ниже.

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

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

Назначение кнопок:
  • L (Left) смещение фигуры влево.
  • R (Right) смешение фигуры вправо.
  • T (Turn) поворот фигуры на 90° по часовой стрелке.
  • D (Down) сброс фигуры вниз (ускорение падения фигуры).

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

Код может показаться немного громоздким. Для понимания кода рекомендуем сначала прочитать раздел «алгоритм работы» следующий сразу за кодом. А потом ознакомиться с комментариями в строках самого кода.

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

  • В начале скетча (до кода setup) выполняются следующие действия:
    • Подключаем графическую библиотеку iarduino_OLED для работы с Trema OLED дисплеем.
    • Объявляем объект myOLED указывая адрес дисплея на шине I2C, он должен совпадать с адресом установленным переключателем на обратной стороне платы OLED дисплея.
    • Объявляем константы pinBtnL, pinBtnR, pinBtnT, pinBtnD, pinSeed с указанием номеров выводов Arduino, которые будут задействованы в скетче.
    • Объявляем константы GAME_OFF, GAME_ON, GAME_OVER для удобочитаемости скетча.
    • Подключаем шрифты и картинки предустановленные в библиотеке myOLED.
    • Определяем константы с настраиваемыми значениями. Меняя эти значения можно менять размеры игрового стола, размеры фигур, скорость игры и время «залипания» кнопок.
    • Объявляем массивы и переменные участвующие в работе скетча.
    • Объявляем функции используемые в скетче.
  • В коде setup выполняются следующие действия:
    • Инициируем работу с Trema OLED дисплеем и запрещаем автоматический вывод данных.
    • Указываем кодировку текста в скетче (если требуется).
    • Конфигурируем выводы к которым подключены кнопки.
    • Готовим корректную работу функции random() для генерации псевдослучайных чисел.
    • Выводим анимированное приветствие (текст «Тетрис» с появляющимися фигурами).
    • Переводим состояние игры в GAME_OFF «Не играем» (ждём нажатие любой кнопки).
  • В коде loop сначала выполняется чтение состояний кнопок, после чего выполняется 1 из 3 частей:
    • «Не играем» — эта часть кода ожидает нажатия на любую кнопку. Если любая кнопка будет нажата, будут подготовлены переменные, прорисуется игровое поле и игра перейдёт в состояние GAME_ON «Играем».
    • «Играем» — эта часть кода является основной. Здесь в 18 строках кода реализован весь алгоритм игры. Он более подробно описан ниже.
    • «Игра завершена» — эта часть кода содержит анимацию закраски и очистки игрового стола, вывод текста «КОНЕЦ ИГРЫ», вывод анимированного приветствия и перевод игры в состояние GAME_OFF «Не играем».
  • Весть алгоритм игры полностью реализован в разделе «Играем» который состоит из 4 частей:
    (каждая часть этого раздела заключена в тело оператора if).
    • Первая часть сдвигает фигуру на игровом столе влево. Код в теле оператора if выполняется только при нажатии на кнопку Left. Единственная функция shiftFigure() в теле оператора if, выполняет сдвиг фигуры игрового стола на одну клетку. Параметр функции равный 1 указывает сдвинуть фигуру влево.
    • Вторая часть сдвигает фигуру на игровом столе вправо. Код в теле оператора if выполняется только при нажатии на кнопку Right. Единственная функция shiftFigure() в теле оператора if, выполняет сдвиг фигуры игрового стола на одну клетку. Параметр функции равный 2 указывает сдвинуть фигуру вправо.
    • Третья часть выполняет поворот фигуры на игровом столе. Код в теле оператора if выполняется только при нажатии на кнопку Turn. Единственная функция turnFigure() в теле оператора if, выполняет поворот фигуры на 90°. Первый параметр функции равный 1 указывает что повернуть требуется фигуру на игровом столе.
    • Четвёртая часть выполняет сдвиг фигуры игрового стола на одну клетку вниз. Код в теле оператора if выполняется как от нажатия на кнопку Down, так и по достижении времени tmrShift. Параметр функции равный 3 указывает сдвинуть фигуру вниз. Отпускание кнопки Down не заблокирует выполнение кода в теле оператора if при следующем проходе цикла loop (Если нажать и отпустить кнопку Down, то фигура будет сдвигаться вниз пока не достигнет дна или других фигур).
      Код в теле оператора If выполняет следующие действия:
      • Обновляем время tmrShift для следующего сдвига фигуры вниз на игровом столе.
      • Сдвигаем фигуру игрового стола на 1 клетку вниз. Проверяя не достигла ли фигура дна игрового стола или другой фигуры на игровом столе. Если не достигла, то на этом выполнение данного участка кода будет закончено.
      • Если фигура достигла дна игрового стола или другой фигуры (закончила падение), то выполняются следующие действия:
        • Проверяем наличие заполненных строк игрового стола, если они есть, то они удаляются, со сдвигом всего что находится выше и добавлением бала игроку.
        • Сбрасываем флаг нажатия на кнопку Down (на случай если фигура падала принудительно)
        • Обновляем текущий уровень игры в соответствии со значением счётчика созданных фигур.
        • Увеличиваем счётчик созданных фигур.
        • Выводим номер текущего уровня игры и количество набранных баллов.
        • Создаём будущую фигуру с выводом её изображения в поле справа от игрового стола, а ту фигуру которая ранее находилась в этом поле переносим на верх игрового стола (она станет новой фигурой в игре).
        • Если новую фигуру не удалось разместить на игровом столе (ей мешают другие фигуры), значит игра закончена, переводим состояние игры в GAME_OVER «Игра завершена».
      • Действия перечисленные выше выполняются вызовом функций:
        • shiftFigure(); — выполняет сдвиг фигуры на одну клетку игрового стола и возвращает false если сдвиг невозможен.
        • turnFigure(); — поворачивает фигуру игрового стола на 90°.
        • checkTable(); — проверяет наличие заполненных строк игрового стола, возвращая true или false.
        • deletTableRows(); — удаляет все заполненные строки с игрового стола, возвращая количество удалённых строк.
        • createNewFigure(); — создаёт будущую фигуру а предыдущую будущую фигуру делает новой на игровом столе, возвращая false если не удалось вставить фигуру на игровой стол.
Читать еще:  Делаем подставку под патроны при снаряжении

Все строки скетча (кода программы) прокомментированы, так что Вы можете подробнее ознакомиться с кодом прочитав комментарии строк.

Как сделать тетрис классический

Дисплей от Nokia 5110 — это наверное самый дешевый дисплей который можно найти для своих проектов на Arduino. На базе него мы разберемся с вопросом: «Как же сделать тетрис-игру?@

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

Избалованные i2c шиной скажут «фу», ведь у нас 4 провода управления SCLK, DIN, DC, CE и RTS которые соответственно подключаются к Arduino, 3, 4, 5, 6, 7. Не забываем подключить питание 3.3 вольта, и землю.

Для рисования будем использовать библиотеку Adafruit GFX Library. В архиве с ней есть примеры использования.
Для управления игрой используем ИК пульт от телевизора. Сигнал будет принимать датчик TL1838.

Я использовал Arduino Uno, т.к. она уже имеет стабилизатор на 3.3 вольт.
Подключение IR приемника:
pin 8 — IR (управляющий). Питание на +5V и GND.
Подключение пьезодинамика:
pin 9 — speaker, Земля на GND.

Игра поддерживает привязку к любому пульту. Для этого достаточно в начале игры, на вопрос «Нажмите ОК» нажать на пульте кнопку, которая будет отвечать за вращение фигуры. Если пульт игре уже знакомый, то игра сразу запустится. Если пульт новый, то код кнопки ОК не совпадет с запомненным и игра потребует последовательно нажать кнопки «Влево», «Вправо» и «Вниз». Эти кнопки будут записаны в энергонезависимую память Ардуино и впоследствии именно этот пульт будет узнаваться сразу по нажатию кнопки «ОК».

При «проваливании» на собранную строку будет воспроизводиться писк. Он реализован на особенности нескольких пинов Ардуино (в нашем случае 9) выдавать ШИМ с заданной частотой. Игра поддерживает все атрибуты нормальной игры. Ту и подсказка следующей фигуры и текущий счет. Игра ведет учет рекордов. Это значение хранится в энергонезависимой памяти Ардуино. Чтобы сбросить рекорд, достаточно изменить в скетче значение flfirst=1234 на любое другое. В игре также идет автоувеличение скорости падения через каждые 30 списанных строчек, так что, бесконечно долго поиграть не получится ). Скетч не оптимизировался и тщательно не прогонялся, а был написан на досуге в свое удовольствие. Если кто обнаружит ошибку — пишите. О ©. Скетч разрешается править для себя как угодно. Только при публикации где-либо своих вариантов ссылку на первоисточник-муську указывайте ). Для чего делал — длинные выходные + «из любви к искусству». Была бы дочка маленькой, сделал бы ей, наверное, мини игровой автомат для кукольной комнатки на 8 марта, как раз успел бы. Добавил бы несколько игр типа Змейки и Арканоида, а корпус вырезал бы из текстолита, наверное. Только дочка в этом году уже докторскую защищает, так, что мимо, но может кому еще эта идея пригодится ).

Читать еще:  Делаем микрофон из спичечного коробка и карандашей

Тетрис на базе Arduino и двухцветных светодиодных матриц

Один из наборов для самостоятельной сборки jolliFactory поставляется с модулем управления двухцветной светодиодной матрицей. Данный модуль позволяет соединять последовательно большое количество модулей в соответствии с требованиями вашего проекта.

С помощью данных модулей было изготовлено несколько интересных устройств:

Видеоигра тетрис была выпущена в 1984 году и имела огромный успех для портативной ручной приставки Game Boy, выпущенной в 1989 году, которая сделала ее популярной до настоящего времени.

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

Мы попытались найти подобные проекты в сети Интернет и получили некоторую информацию, которую впоследствии адаптировали для создания простой игры тетрис на базе Arduino и двухцветной светодиодной матрицы.

Для выполнения данного проекта необходимы базовые знания электроники, некоторые умения по пайке компонентов и знание микроконтроллера Arduino.

Ниже показано видео работы готового устройства.

Шаг 1: Изготовления драйвера управления двухцветным светодиодным модулем

В данном проекте используются две светодиодные матрицы, управляемые Arduino Nano. Нам понадобится два набора Bi-color (Red/Green) LED Matrix Driver Module Kits от jolliFactory. Каждый из этих модулей использует две микросхемы-драйвера MAX7219 для управления двухцветной светодиодной матрицей. Данные микросхемы идеально пригодны для нашего проекта, поскольку снимают основную работу с микроконтроллера и облегчают разводку логических элементов устройства.

Двухцветные светодиодные матрицы можно приобрести здесь.

Данный набор имеет все необходимые компоненты. Для сборки нужны некоторые навыки пайки.

Ниже показано видео по сборке светодиодного модуля:

Шаг 2: Подключение

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

Для звукового выхода игровой приставки мы использовали 8-омный динамик мощностью 0.5 ватта, управляемый напрямую одним из цифровых выводов Arduino через резистор 100 ом. В данном проекте используется основной звуковой тон. Для портативной приставки будет вполне достаточно невысокого уровня громкости, регулируемого с помощью простых настроек.

Для навигации и вращения блоков игры тетрис понадобится SPST панель с четырьмя нажимными кнопками.

Необходимо использовать подтягивающие резисторы номиналом 10 кОм для входных выводов DATA IN, CLK и LOAD. При первой подаче питания на микроконтроллер или при его сбросе линии ввода/вывода будут «висеть» в воздухе. Микросхема MAX7219 увидит это как достоверные данные и начнет отображать «мусор», пока микроконтроллер не начнет отрабатывать управляющую программу. Чтобы этого не происходило необходимо использовать подтягивающие резисторы. Для снижения общего количества компонентов можно не использовать подтягивающие резисторы номиналом 10 кОм для входных выводов DATA IN и CLK.

За исключением двух двухцветных светодиодных модулей и четырех нажимных кнопок, мы выполнили монтажные соединения всей схемы на небольшой перфорированной плате размером около 60 мм x 60 мм.

Примите во внимание, что на фото показаны четыре нажимные кнопки, устанавливаемые на общей перфорированной плате. Мы первоначально использовали их для управления игровой приставкой. Однако после изготовления корпуса мы решили использовать панель с установленными на ней четырьмя нажимными кнопками для более удобного управления игрой. Мы соединили параллельно нашу панель с нажимными кнопками с небольшими нажимными кнопками на печатной плате, поэтому управление может выполняться нажимными кнопками на печатной плате или на панели.

Читать еще:  Делаем детскую мебель из вторсырья

Шаг 3: Программирование платы Arduino

В плату Arduino необходимо загрузить скетч для управления дисплеем.

Для этого мы использовали Arduino IDE V1.03.

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

Шаг 4: Корпус и окончательная сборка

Поскольку данный проект задумывался для сайта FUN factor без намерения использовать устройство длительное время, мы не уделили большое внимание созданию надежного корпуса. Однако изготовленный корпус позволяет удобно держать устройство и комфортно играть.

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

Делаем Тетрис на Arduino



Добавим еще несколько библиотек и начнем писать код, память и во все закончится. Автор принципиально не использует, например, arduino mega, где памяти больше. Цель сделать игру именно на arduino nano, используя простые, стандартные и всем известные инструменты, но в то же время нестандартные подходы и «костыли» и с их помощью добиться максимально оптимального кода.

Первым «костылем» будет отказ от отдельного хранение в памяти позиций фигур и вообще всего, что творится на экране. Нам нужно хранить координаты точек подающей фигуры и координаты точек уже упавших фигур, то есть как максимум нам нужен еще 1 массив, двумерный 16 на 16, а это еще целых 256 байт.

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

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

Для обработки кнопок, автор также использует свою библиотеку. Схема подключения кнопок до смешного проста: 4 кнопки, 8 проводов.

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

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

Собственно, теперь осталось случайно выбирать номер фигуры и отрисовывать ее вокруг падающего блока. Здесь мы для всех 3-ех оставшихся блоков берем из флеш-памяти координаты, переводим их в глобальные координаты матрицы и включаем светодиоды. Кстати, цвет тоже выбирается случайно из 6-ти самых простых и ярких цветов пространства rgb. Угол поворота фигуры при начале раунда тоже задается случайно, а при нажатии кнопки вверх, просто берем для отрисовки следующий набор координат и вращаем по часовой стрелке. Перемещение фигуры работает все также. Сначала стираем фигуру на предыдущем положении, то есть рисуем ее черным цветом, затем в новом положении рисуем уже текущим цветом фигуры. При повороте, опять же, стираем старое положение и просто рисуем новое.

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


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

Кстати, при нажатии кнопки вниз, фигура с большой скоростью устремляется вниз и занимает свое место.


Счет выводится цифрами, которые хранятся в памяти как набор единиц и нулей, по которым далее включаются или не включаются светодиоды. Собственного так выглядит тетрис, написанный под адресную матрицу. Благодарю за внимание. До новых встреч!

Ссылка на основную публикацию
Статьи c упоминанием слов:
Adblock
detector