adamgreig/arduino_tetris
Use Git or checkout with SVN using the web URL.
Work fast with our official CLI. Learn more.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.markdown
- Arduino
- 128 x 96 LCD from Sparkfun: http://www.sparkfun.com/commerce/product_info.php?products_id=8844
- Four standard push buttons
A 10×20 char grid represents the game grid. A struct that holds four two-byte Positions represents the piece in play. The code then loops through, deciding whether to apply gravity each loop based on how long it was since gravity was previously applied, then checking for a collision if so. If a collision happened the current piece is saved to the grid and a new one is generated. The grid is checked for newly completed lines and if any are found they’re cleared and the player gets a point. In the meantime, the four buttons are on the pin change interrupt, and drive the move_left, move_right, rotate and drop functions. Interrupts are disabled each time one happens and reenabled after drawing each frame to help stop accidental repeats. At the end of the game, when a block is placed in the top row, the grid is filled with red and then a number of squares are lit up green to represent the player’s score. This is problematic with a score of over 200, but that’s a pretty unlikely edge case.
About
Play Tetris on an Arduino, using a 128×96 colour LCD and four buttons
Урок 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 если не удалось вставить фигуру на игровой стол.
Все строки скетча (кода программы) прокомментированы, так что Вы можете подробнее ознакомиться с кодом прочитав комментарии строк.
The Tetris © GPL3+
Relive your childhood memories with the new and better Tetris!
![]() |
|
Remember those Summer Vacations when you and your cousins used to compete with each on the evergreen gaming console of Tetris?!
Well guess what, you can make the same thing but a little better using just an Arduino and a LED display matrix!
Let’s move on to the project details.The major components I used were an Arduino Nano, a MAX7219 LED Matrix Display and HC-05 for wireless connectivity.The Main features of this Gaming Console are:1. Wireless Connectivity through an android app created on MIT App Inventor2. Brightness Control3. High Score and Current Score Saving4. Iconic Background Music and a special Indicator sound when a Line is cleared.5. Special Levels, difficulty increases with score.
Let’s start with the components.
MAX7219 LED Matrix Display We used a 4-daisy chained LED Matrix where two of them were used as the gaming area and one for High Score and Current Score Evaluation and the last one for Animations etc.We can find libraries in using which we can very easily control the LED Matrix and do various functions like scrolling, displaying shapes etc.We designed the gameplay UI and experience according the old generic game and tried to enhance it using features of our own.
HC-05 Bluetooth Module This is a very efficient device used for wireless connections as it is economical and simple to use. This uses UART protocol to communicate with the microcontroller hence uses only 4 pins, namely VCC, GND, RX, TX.An android app was made and was interfaced with the HC-05 through Arduino to control the gaming console using an Android Device.
Arduino Nano
A compact and a highly efficient Microcontroller.
Arduino provides us with an easy UI and a coding environment so we can write the functions easily. You can find the code written in Arduino IDE below.
Now let’s take a look at the circuit!
We used a zero PCB board and copper cladded wires and a solder machine to make the whole circuit. We didn’t have fabrication facilities at the time or else we could have made the whole custom PCB in Eagle CAD. If you want it can be done quite easily.But I gues you can get and idea about the circuit from this image above.
We designed and made the whole circuit in my hostel room. You can see the arrangement below…
Just to mention a few things, we didn’t use any onboard memory to save the high score, we just used the Arduino’s EEPROM to save the score so that we can access the score even after plugging off the power and turning it on again. You can find the EEPROM configuration in the code attached.And we could have a used an OLED or a LCD display separately to display score etc and made the device more compact but as we had 4 Dasiy Chained Display Matrix we decided to go with it. You can change the code and configure it according to your needs etc.
So, this was a quick overview of how we made our very own Gaming Console using some easy electronics and a bit of coding! Have fun. :)