Доработка функции Draw
Функция Draw, созданная в предыдущем уроке, нуждается в доработке для отображения змейки и фрукта на игровом поле. Добавим условные операторы if:
if (i == snakeY && j == snakeX) {
std::cout << "0"; // Символ змейки
} else if (i == fruitY && j == fruitX) {
std::cout << "F"; // Символ фрукта
} else {
std::cout << " "; // Пробел для пустого пространства
}
Этот код проверяет координаты i и j текущей клетки поля. Если они совпадают с координатами змейки (snakeY, snakeX), выводится символ «0»; если с координатами фрукта (fruitY, fruitX), выводится «F»; в остальных случаях — пробел. Небольшое смещение змейки относительно нужной позиции связано с добавлением +1 к координатам при рисовании поля в предыдущем уроке. Для исправления этого, нужно отнять -1 из начальных координат x и y змейки.
Обработка ввода с клавиатуры
Для обработки нажатий клавиш используем библиотеку conio.h и функцию _kbhit(). Эта функция возвращает true, если нажата клавиша, и позволяет отслеживать нажатия без блокировки терминала.
#include <conio.h>
// ...
if (_kbhit()) {
switch (_getch()) {
case 'a': dir = Left; break;
case 'd': dir = Right; break;
case 'w': dir = Up; break;
case 's': dir = Down; break;
case 'x': gameOver = true; break;
}
}
Этот код проверяет, нажата ли клавиша. Если да, то с помощью _getch() определяется нажатая клавиша, и в зависимости от неё изменяется направление движения змейки (dir) или завершается игра (gameOver = true).
Логика движения и обработка столкновений
Функция Logic содержит логику движения змейки. Используем switch для обработки направления движения:
switch (dir) {
case Left: snakeX--; break;
case Right: snakeX++; break;
case Up: snakeY--; break;
case Down: snakeY++; break;
}
Добавим проверку на выход за границы игрового поля:
if (snakeX >= width || snakeX < 0 || snakeY >= height || snakeY < 0) {
gameOver = true;
}
Этот код проверяет координаты змейки, и если она выходит за пределы поля, устанавливает gameOver в true, завершая игру.
Поедание фрукта и счёт
Добавим логику поедания фрукта и начисления очков:
if (snakeX == fruitX && snakeY == fruitY) {
score += 10;
// Генерация новых координат для фрукта (код аналогичен генерации начальных координат)
}
При совпадении координат змейки и фрукта, к счету добавляется 10 очков, а фрукт перемещается в случайное место на поле. В функции Draw добавляем вывод текущего счёта:
std::cout << "Score: " << score << std::endl;