Реализация змейки
- Войдите на сайт для отправки комментариев
Вс, 18/04/2021 - 19:28
Здравствуйте, знатоки. Помогите, пожалуйста, в реализации змейки.Библиотека для дисплея от adafruit.Отработка кнопок GyverButton. Если что - это кусок скетча для игровой мини консоли с несколькими играми. Сделал движение змеи, условия игры, яблоки,счет и тд.А как ей движение то задать?Заранее спасибо.
void snakeEngine() {
uint32_t timer;
byte headX = random(5, 31);
byte headY = random(2, 15);
byte snakeLenght = 1;
byte snakeTailX[snakeLenght];
byte snakeTailY[snakeLenght];
bool appleEat = true;
byte appleX;
byte appleY;
byte dir; // 1 - F 2 - B 3 - L 4 - R
long vel = 250;
bool lose = false;
byte i;
while (lose == false) {
if (appleEat == true) {
appleX = random(31);
appleY = random(15);
appleEat = false;
}
if (L.isClick()) {
if (dir != 4) {
dir = 3;
}
}
if (R.isClick()) {
if (dir != 3) {
dir = 4;
}
}
if (UP.isClick()) {
if (dir != 2) {
dir = 1;
}
}
if (DOWN.isClick()) {
if (dir != 1) {
dir = 2;
}
}
if (millis() - timer >= vel) {
timer = millis();
snakeTailX[1] = headX + 4;
snakeTailY[1] = headY + 4;
switch (dir) {
case 1: //FORWARD
headY = constrain(headY - 1, 0, 15);
break;
case 2: //BACKWARD
headY = constrain(headY + 1, 0, 15);
break;
case 3: //LEFT
headX = constrain(headX - 1, 0, 31);
break;
case 4: //RIGHT
headX = constrain(headX + 1, 0, 31);
break;
}
}
if (DOWN.isHold() or UP.isHold() or L.isHold() or R.isHold()) {
vel = 50;
}
if (DOWN.isRelease() or UP.isRelease() or L.isRelease() or R.isRelease()) {
vel = 250;
}
if (headX == appleX and headY == appleY) {
snakeLenght++;
appleEat = true;
}
if (headX == 0 or headX == 31 or headY == 0 or headY == 15) {
display.setTextSize(2);
display.setCursor(15, 26);
display.print("YOU LOSE");
display.display();
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.display();
break;
}
if (S.isClick()) {
break;
}
display.fillRect(headX * 4, headY * 4, 4, 4, WHITE);
display.fillRect(appleX * 4, appleY * 4, 4, 4, WHITE);
display.fillRect(snakeTailX[i] * 4, snakeTailY[i] * 4, 4, 4, WHITE);
display.setCursor(0, 0);
display.print(snakeLenght);
display.display();
display.clearDisplay();
}
}
Сделал движение змеи, условия игры, яблоки,счет и тд.А как ей движение то задать?
Вы уж определитесь сделали или не сделали движение. В коде попытка сделать есть. В чем проблема то ?
Вы уж определитесь сделали или не сделали движение.
может верхний код не ТС, он его где-то списал?
Простите, не движение, а длинну змейки
может верхний код не ТС, он его где-то списал?
Не просто списал, но и творчески доработал )
Простите, не движение, а длинну змейки
Почему у вас в 45 и 46 в массив хвоста заносятся координаты головы +4 ? Что такое i в строке 94 ? Башка змеи разве не двигается ? Что на экране видно ?
Та не списал я, это первый мой более менее сложный скетч, так что сильно не пинайте=).С строках 45 и 46 я пытался хранить в массиве все элементы змейки кроме головы, а потом выводить их через for.Нумерацию в массиве я начал с 1, чтобы можно было выводить хвост змеи через переменную длинны змеи.Число 4 это волшебное число в этом коде.Дело в том, что я сделал игровое поле как сетку 16 на 32. А дисплей 128 на 64...
Это оно в конце скетча волшебное когда на экран выводите, в 45 и 46 оно не нужно, хотите отступ от края экрана - сделайте это когда рисуете. Нумерация элементов по длине хвоста - это ладно, но единственное место, где вы работаете с хвостом, кроме 45 и 46 - это 94, в ней у вас переменная i, если вы сможете объяснить что это и зачем - я прям удивлюсь.
Вот над этим подумайте пока:
Делать clearDisplay() постоянно хреновый вариант - у вас будет моргать дисплей и, возможно, тормозить. Координаты всех объектов вы знаете - башку рисуйте, конец хвоста стирайте.
Массив хвоста по вашей задумке растет с удлинением змеи. Вы запоминаете координаты башки перед её движением так snakeTailX[1] = headX + 4; snakeTailY[1] = headY + 4; теперь вопрос - на следующем шаге у вас координаты башки опять попадут в [1], но вы ничего не делаете с массивом, т.е. просто перезатираете координаты в [1]. Чего то явно не хватает... ммм ?
( про гайверовские кнопки ничего не скажу, просто надеюсь, что оно работает :) )
Это олед дисплей, и на нем это выглядит нормально, не мерцает.Весь скетч целиком огромный, а это лишь функция игры, которую я вызываю.Про библиотеку гайвера - это довольно удобно, и да , это работает.
Это олед дисплей, и на нем это выглядит нормально, не мерцает.
Это довольно странно, возможно связано с небольшой областью отрисовки, но советую проверить вариант без cleardisplay. Если бы не мерцало я бы так тоже делал )
Вы так и не написали у вас башка змеи перемещается ? Если нет - могут быть еще проблемы не связанные с массивом хвоста.
Вот я храню всю змею в одном массиве, через for его заполняю и вывожу, и это уже почти змейка.
void snakeEngine() { uint32_t timer; byte snakeLenght = 1; byte snakeX[50]; byte snakeY[50]; bool appleEat = true; byte appleX; byte appleY; byte dir; // 1 - F 2 - B 3 - L 4 - R long vel = 150; bool lose = false; int i; snakeX[0] = 5; snakeY[0] = 5; while (lose == false) { if (appleEat == true) { appleX = random(31); appleY = random(15); appleEat = false; } if (L.isClick()) { if (dir != 4) { dir = 3; } } if (R.isClick()) { if (dir != 3) { dir = 4; } } if (UP.isClick()) { if (dir != 2) { dir = 1; } } if (DOWN.isClick()) { if (dir != 1) { dir = 2; } } for (int i = snakeLenght; i > 0; i--) { snakeX[i] = snakeX[i - 1]; snakeY[i] = snakeY[i - 1]; } if (millis() - timer >= vel) { timer = millis(); switch (dir) { case 1: //FORWARD snakeY[0] = constrain(snakeY[0] - 1, 0, 15); break; case 2: //BACKWARD snakeY[0] = constrain(snakeY[0] + 1, 0, 15); break; case 3: //LEFT snakeX[0] = constrain(snakeX[0] - 1, 0, 31); break; case 4: //RIGHT snakeX[0] = constrain(snakeX[0] + 1, 0, 31); break; } } if (DOWN.isHold() or UP.isHold() or L.isHold() or R.isHold()) { vel = 50; } if (DOWN.isRelease() or UP.isRelease() or L.isRelease() or R.isRelease()) { vel = 250; } if (snakeX[0] == appleX and snakeY[0] == appleY) { snakeLenght++; appleEat = true; } if (snakeX[0] == 0 or snakeX[0] == 31 or snakeY[0] == 0 or snakeY[0] == 15) { display.setTextSize(2); display.setCursor(15, 26); display.print("YOU LOSE"); display.display(); delay(2000); display.clearDisplay(); display.setTextSize(1); display.display(); break; } if (S.isClick()) { break; } display.fillRect(appleX * 4, appleY * 4, 4, 4, WHITE); for (i = 1; i < snakeLenght; i++) { display.fillRect(snakeX[i] * 4, snakeY[i] * 4, 4, 4, WHITE); } display.fillRect(snakeX[0] * 4, snakeY[0] * 4, 4, 4, WHITE); display.setCursor(0, 0); display.print(snakeLenght); display.display(); display.clearDisplay(); } }Теперь похоже на правду. Какие то проблемы остались ?
Спасибо за помощь, теперь это полноценная змейка.