
Для реализации данной игры нам понадобятся следующие компоненты:
- 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
Ну а сам процесс игры и описание некоторых строчек кода, вы сможете увидеть ниже в Видео: