Для реализации данной игры нам понадобятся следующие компоненты:
- LCD дисплей Nokia 5110: http://ali.pub/1m0gbs
- Ir приемник и пульт: http://got.by/1m0gqd
- SensorShield: http://ali.pub/1m0h0o
- Контактные провода: http://ali.pub/1m0h4y
- Arduino uno: http://ali.ski/xxTA2
Прежде чем приступить к материалу, я Вас попрошу, если нравится то, что я делаю и хотите следить за моей деятельностью, то рекомендую подписаться на мой телеграмм канал: https://t.me/ypavla
Там я публикую новости о вышедших видео, статьях и разные устройства для умного дома и не только показываю.
Спасибо за внимание, теперь продолжим.
Подключение дисплея:
LCD | RST | CE | DC | DIN | CLK | VCC | Light | GND |
Arduino | D9 | D10 | D11 | D12 | D13 | 3.3v | GND | GND |
Подключение ИК-приемника:
ИК-приемник | OUT | GND | VCC |
Arduino | D6 | GND | 3.3v |
Каждая кнопка разных ИК-Пультов имеет свой уникальный код. Для того чтоб узнать какой код у нужной нам кнопки, нужно загрузить скетч, который находится ниже и в программе FLProg просканировать нужные нам кнопки. В видео в конке статьи, наглядно показано, как с помощью программы FLProg просканировать кнопки Ик-Пульта.
#include <IRremote.h> int RECV_PIN = 6; IRrecv irrecv(RECV_PIN); decode_results results; void setup() { Serial.begin(9600); irrecv.enableIRIn(); } void dump(decode_results *results) { int count = results->rawlen; String type; if (results->decode_type == UNKNOWN) { type = String("Unknown encoding"); } else if (results->decode_type == NEC) { type = String("NEC"); } else if (results->decode_type == SONY) { type = String("SONY"); } else if (results->decode_type == RC5) { type = String("RC5"); } else if (results->decode_type == RC6) { type = String("RC6"); } else if (results->decode_type == PANASONIC) { type = String("PANASONIC"); } else if (results->decode_type == JVC) { type = String("JVC"); } Serial.write (1); Serial.write (2); Serial.print(results->value, HEX); Serial.write (3); Serial.write (2); Serial.print(type); Serial.write (3); Serial.write (2); Serial.print(results->decode_type); Serial.write (3); Serial.write (2); Serial.print(results->bits,DEC); Serial.write (3); Serial.write (4); } void loop() { if (irrecv.decode(&results)) { dump(&results); irrecv.resume(); // Receive the next value } }
Данный скетч сканирует коды кнопок в 16 системе счисления, а в игру нам нужно будет вставить коды в 10 системе. Для этого воспользуемся любым калькулятором который переводит 16 в 10.
Ну вот мы плавно подошли к самому коду игры “Змейка” на Ардуино. Данный код приведен здесь:
#include <Adafruit_GFX.h> #include <Adafruit_PCD8544.h> #include <SPI.h> #include <IRremote.h> Adafruit_PCD8544 display = Adafruit_PCD8544(13, 12, 11, 10, 9);// инициализация дисплея(пины порта подключения дисплея) int RECV_PIN = 6;// подключаем пульт на 6й порт IRrecv irrecv(RECV_PIN); //Создаем объект получения сигнала с определенного порта decode_results results; //Переменная, хранящая результат //текущее направление змейки boolean dl = false, dr = false, du = false, dd = false; int x[50], y[50], i, slength, tempx = 10, tempy = 10, xx, yy; unsigned int high; uint8_t bh, bl; int xegg, yegg; int freq, tb; int l, r, u, d, p; unsigned long time = 280, beeptime = 50; int score = 0, flag = 0; void setup() { Serial.begin(9600); display.begin(); irrecv.enableIRIn(); // Начинаем прием c IR пульта //Приветствие на дисплей display.setContrast(20); display.clearDisplay(); display.drawRoundRect(0, 0, 84 , 25, 1, 2); display.setTextSize(2); display.setTextColor(BLACK); display.setCursor(12, 6); display.println("SNAKE"); display.setTextSize(1); display.setTextColor(BLACK); display.setCursor(12, 29); display.println(""); display.setCursor(29, 29); display.println("2016"); display.display(); delay(5000); slength = 8; xegg = (display.width()) / 2; yegg = (display.height()) / 2; display.clearDisplay(); display.drawRect(0, 0, 84, 48, 1); display.setCursor(4, 2); display.print("S: R:");//надпись score и record display.setCursor(22, 2); display.print(score); display.setCursor(64, 2); display.print(high); display.drawRect(0, 0, 84, 11, 1); //координаты for (i = 0; i <= slength; i++) { x[i] = 25 - 3 * i; y[i] = 30; } for (i = 0; i < slength; i++) //Рисуем змею { display.drawCircle(x[i], y[i], 1, BLACK); } display.display(); dr = true; } void loop() { movesnake(); } void movesnake() { if (flag == 0) { direct(); } if (millis() % time == 0) { if (flag == 0) { if (dr == true) { tempx = x[0] + 3; tempy = y[0]; } if (dl == true) { tempx = x[0] - 3; tempy = y[0]; } if (du == true) { tempy = y[0] - 3; tempx = x[0]; } if (dd == true) { tempy = y[0] + 3; tempx = x[0]; } } flag = 0; checkgame(); checkegg(); //изменение координат for (i = 0; i <= slength; i++) { xx = x[i]; yy = y[i]; x[i] = tempx; y[i] = tempy; tempx = xx; tempy = yy; } //перерисовка змейки и цели drawsnake(); } } void checkgame() { for (i = 1; i < slength; i++) { //Проверяет, что рекорд побит и вывод нового результата high = (((0xff00 + bh) << 8) + bl); if (score > high) { high = score; bh = (high >> 8); bl = high & 0xff; display.fillRect(61, 1, 20, 9, 0); display.setCursor(65, 2); display.print(high); } //Проверка касания границ игрового поля if ((x[0] <= 1 || x[0] >= 83) || (y[0] <= 12 || y[0] >= 47) || (x[i] == x[0] && y[i] == y[0]) ) { //Если коснулась, то проигрыш. Выводит результаты display.clearDisplay(); display.fillRoundRect(0, 0, 84 , 31, 1, 2); display.setTextColor(WHITE); display.setTextSize(2); display.setCursor(18, 1); display.print("GAME"); display.setCursor(18, 16); display.print("OVER"); display.setTextColor(BLACK); display.setTextSize(1); display.setCursor(12, 33); display.print("SCORE"); display.setCursor(60, 33); display.print(score); display.setCursor(12, 41); display.print("RECORD"); display.setCursor(60, 41); display.print(high); display.display(); //ждем 5 сек и перезапускаем игру delay(5000); //очищаем дисплей display.clearDisplay(); //возвращаем к исходному положению slength = 8; score = 0; time = 280; redraw(); } } } void checkegg() //змейка ест добычу { //Проверяем что у змеи и добычи одни и те же координаты if (x[0] == xegg or x[0] == (xegg + 1) or x[0] == (xegg + 2) or x[0] == (xegg - 1)) { if (y[0] == yegg or y[0] == (yegg + 1) or y[0] == (yegg + 2) or y[0] == (yegg - 1)) { //змея увеличивается, значение очков плюсуем score += 1; display.fillRect(21, 1, 20, 9, 0); display.setCursor(22, 2); display.print(score); slength += 1; if (time >= 90) { time -= 10; } display.fillRect(xegg, yegg, 3, 3, WHITE); display.display(); //перерисовываем добычу в новом месте xegg = random(2, 80); yegg = random(15, 40); } } } void direct() { if (irrecv.decode(&results)) { //изменение движения если нажимаем ик пульт if (results.value ==16591063 and dr == false) //право { dl = true; du = false; dd = false; tempx = x[0] - 3; tempy = y[0]; flag = 1; } else if (results.value ==16607383 and dl == false)//лево { dr = true; du = false; dd = false; tempx = x[0] + 3; tempy = y[0]; flag = 1; } else if (results.value ==16615543 and dd == false)// вверх { du = true; dl = false; dr = false; tempy = y[0] - 3; tempx = x[0]; flag = 1; } else if (results.value ==16619623 and du == false) //вниз { dd = true; dl = false; dr = false; tempy = y[0] + 3; tempx = x[0]; flag = 1; } irrecv.resume(); } } void drawsnake() { display.fillRect(xegg, yegg, 3, 3, BLACK); display.drawCircle(x[0], y[0], 1, BLACK); display.drawCircle(x[slength], y[slength], 1, WHITE); display.display(); } void redraw() { display.drawRect(0, 0, 84, 48, 1); display.drawRect(0, 0, 84, 48, 1); display.setCursor(4, 2); display.print("S: R:"); display.drawRect(0, 0, 84, 11, 1); display.fillRect(21, 1, 20, 9, 0); display.setCursor(22, 2); display.print(score); display.fillRect(61, 1, 20, 9, 0); display.setCursor(65, 2); display.print(high); xegg = (display.width()) / 2; yegg = (display.height()) / 2; dl = false, dr = false, du = false, dd = false; dr = true; display.setCursor(4, 2); display.print("S: R:"); display.drawRect(0, 0, 84, 11, 1); //возвращаем начальные координаты for (i = 0; i <= slength; i++) { x[i] = 25 - 3 * i; y[i] = 30; } tempx = 33 - 3 * i; tempy = 30; display.display(); }
Ссылка на сам скетч: https://yadi.sk/d/JQIjwqoq3Kbp4X
Ну а сам процесс игры и описание некоторых строчек кода, вы сможете увидеть ниже в Видео: