


Привет. Пришло время использовать светодиодную матрицу и джойстик для реального проекта. А что может быть лучше, чем сделать настоящую игру. Так что, сегодня соберем схему и напишем нашу версию игры змейка для Ардуино.
Содержание
В прошлый раз мы уже сделали обзор на джойстик и управление светодиодом на матрице с его помощью. Посмотрите тот пост, если пропустили или уже забыли.
Для того, чтобы выполнить этот проект нам понадобиться
- Ардуино UNO
- Перемычки
- Макетная плата
- Светодиодная матрица
- Резистор 220 Ом
- Джойстик
- Кабель USB
Мы уже умеем управлять одним светодиодом на матрице с помощью джойстика. Это будет основа нашей змейки. В целом, осталось добавить в программу всего несколько элементов. И она уже будет похожа на игру.
Змейка
В первую очередь сделаем, чтобы змейка двигалась сама, а при движении джойстика только меняла направление движения, если требуется.
Для этого мы должны сохранять предыдущее значение джойстика в переменных. И сравнивать их с текущем положением джойстика.
int OlddX, OlddY;
Текущие значения джойстика по X и Y сравниваются со значениями на предыдущем шаге. И если изменений нет, новое направление движения = старому.
dX = map(dX, 0, 1000, -1, 1);
dY = map(dY, 0, 1000, -1, 1);
if(dX == 0 && dY == 0 && OlddX != dX){
dX = OlddX;
}
if(dY == 0 && dX == 0 && OlddY != dY){
dY = OlddY;
}
int newDirection = last;
Таким образом мы передадим в функцию вычисления следующего шага нужную переменную. Даже если направление движения не изменилось.
Движение в одной строке
Кроме того, нужно учесть движение змейки в одной строке и одном столбце. Чтобы змейка появлялась с другой стороны матрицы, когда она выползает за пределы поля.
Для этого изменим функцию расчета следующего шага с учетом новых требований.
Для движения по оси X это не сложно. Нужно только добавить или отнять 15 клеток от текущего индекса, в зависимости от четности строки.
if( dX != 0 ){ // moving in X direction
if ( row&1 ){
if( col == 0 && dX == 1){ newDirection = last -15; }
else if( col == 15 && dX == -1){ newDirection = last +15; }
else newDirection = last + dX; // четная
} else {
if( col == 0 && dX == 1){ newDirection = last +15; }
else if( col == 15 && dX == -1 ){ newDirection = last -15; }
else newDirection = last - dX; // не четная
}
}
Со столбцами разобраться немного сложнее.
Нужно учесть четность строки, направление движения. Если змейка уползает за 15 строку, то все просто. Новая позиция равна номеру столбца.
А если за первую строку, то максимальное количество светодиодов в матрице — номер столбца.
if( dY < 0){ // moving in Y DOWN direction
if(row == 15 && dY == -1){newDirection = col;}
else if ( row&1 ){
newDirection = last + (col*2)+1; // четная
} else {
newDirection = last + (16-col-1)+(16-col); // не четная
}
}
if( dY > 0){ // moving in Y UP direction
if( row == 0 && dY == 1){ newDirection = 255 - col;}
else if ( row&1 ){
newDirection = last - (last - 16*row) - (16 - col); // четная
} else {
newDirection = last - (col*2)-1; // не четная
}
}
Теперь змейка не выйдет за пределы матрицы и будет двигаться самостоятельно.
Осталось только добавить для нее еды и условия проигрыша. Этим займемся в следующий раз.



Полный текст функции расчета движения
int Snakedirection(int last, int dX, int dY ){
dX = map(dX, 0, 1000, -1, 1);
dY = map(dY, 0, 1000, -1, 1);
if(dX == 0 && dY == 0 && OlddX != dX){
dX = OlddX;
}
if(dY == 0 && dX == 0 && OlddY != dY){
dY = OlddY;
}
int newDirection = last;
if( dX != 0 ){ // moving in X direction
if ( row&1 ){
if( col == 0 && dX == 1){ newDirection = last -15; }
else if( col == 15 && dX == -1){ newDirection = last +15; }
else newDirection = last + dX; // четная
} else {
if( col == 0 && dX == 1){ newDirection = last +15; }
else if( col == 15 && dX == -1 ){ newDirection = last -15; }
else newDirection = last - dX; // не четная
}
}
if( dY < 0){ // moving in Y DOWN direction
if(row == 15 && dY == -1){newDirection = col;}
else if ( row&1 ){
newDirection = last + (col*2)+1; // четная
} else {
newDirection = last + (16-col-1)+(16-col); // не четная
}
}
if( dY > 0){ // moving in Y UP direction
if( row == 0 && dY == 1){ newDirection = 255 - col;}
else if ( row&1 ){
newDirection = last - (last - 16*row) - (16 - col); // четная
} else {
newDirection = last - (col*2)-1; // не четная
}
}
OlddX = dX;
OlddY = dY;
return newDirection;
}
Заключение
Мы написали первую часть игры змейка. Теперь мы можем управлять нашим героем, она двигается по игровому полю сама. Движения за пределы матрицы не происходит. И нам осталось добавить немного кода, чтобы игра стала похожа на настоящую игру.