Классическая змейка на JavaScript в браузере
@labweb
Для работы классической змейки нужно чтобы соблюдались эти условия:
1) игровое поле состояло из клеток
2) по этому полю змейка все время двигалась
3) в поле случайным образом появлялся кубик
4) кубик исчезал и появлялся на новом месте, когда змейка его "съедала"
5) змейка удлинялась после "поедания" на одну клетку.
Шаг 1: Добавляем HTML
<!DOCTYPE html> <html> <head> <title>WebLab - Snake</title> </head> <body> </body> </html>
Шаг 2: Добавляем CSS, благодаря ему наше игровое поле будет по центру и страница иметь зелёный цвет
html,
body {
height: 100%;
margin: 0;
}
body {
background: #89AC76;
display: flex;
align-items: center;
justify-content: center;
}
/*Рамка игрового поля*/
canvas {
border-style: solid;
border-width: thick;
border-color: black;
}
Шаг 3: Добавляем игровое поле, для этого в body нужно добавить следующее
<canvas width="400" height="400" id="game"></canvas>
Шаг 4: Добавляем JavaScript
Этап 1: Задаём все переменные
// Находим canvas в документе
var canvas = document.getElementById('game');
// Указываем каким образом рисуем в canvas
var context = canvas.getContext('2d');
// Размер одной клетки - 16 пикселей
var grid = 16;
// Скорость змейки
var count = 0;
// Модель змейки
var snake = {
// Старт змейки
x: 160
, y: 160
, // Со старта змейка двигается вниз
dx: 0
, dy: grid
, // Хвост
cells: []
, // Длина змейки
maxCells: 2
};
// Кубик, который должна собирать змейка
var cube = {
// Начальные координаты кубика
x: 320
, y: 320
};
Этап 2: Генератор случайных чисел, для того чтобы размещать кубики на поле случайным образом
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
Этап 3: Игровой цикл, который работает бесконечно
function weblab() {
// Делает игру в 15 кадров
requestAnimationFrame(weblab);
// Код выполнится один раз для замедления кадров
if (++count < 4) {
return;
}
// Обнуляем скорость
count = 0;
// Очищаем поле
context.clearRect(0, 0, canvas.width, canvas.height);
// Двигаем змейку
snake.x += snake.dx;
snake.y += snake.dy;
// Край поля по горизонтали ---> продолжаем с противоположной строны
if (snake.x < 0) {
snake.x = canvas.width - grid;
}
else if (snake.x >= canvas.width) {
snake.x = 0;
}
// Край поля по вертикали ---> продолжаем с противоположной строны
if (snake.y < 0) {
snake.y = canvas.height - grid;
}
else if (snake.y >= canvas.height) {
snake.y = 0;
}
// Добавляем координаты головы в начало массива
snake.cells.unshift({
x: snake.x
, y: snake.y
});
// Удаляем последний элемент из массива змейки, она двигается и освобождает клетки после себя
if (snake.cells.length > snake.maxCells) {
snake.cells.pop();
}
// Наш кубик
context.fillStyle = 'black';
context.fillRect(cube.x, cube.y, grid - 1, grid - 1);
// Одно движение змейки — один новый квадрат
context.fillStyle = 'black';
// Обрабатываем каждый элемент змейки
snake.cells.forEach(function (cell, index) {
// Cоздаем эффект клеточек
context.fillRect(cell.x, cell.y, grid - 1, grid - 1);
// Когда змейка съела кубик
if (cell.x === cube.x && cell.y === cube.y) {
// Увеличиваем длину змейки
snake.maxCells++;
// Рисуем новый кубик
// Игровое поле разбито на ячейки — 25 в каждую сторону
cube.x = getRandomInt(0, 25) * grid;
cube.y = getRandomInt(0, 25) * grid;
}
// Проверка было столкновение или нет
// Для этого перебираем весь массив и проверяем, есть ли в нем две клетки с одинаковыми координатами
for (var i = index + 1; i < snake.cells.length; i++) {
// Если есть - игра начинается заново
if (cell.x === snake.cells[i].x && cell.y === snake.cells[i].y) {
// Стартовые параметры основным переменным
snake.x = 160;
snake.y = 160;
snake.cells = [];
snake.maxCells = 2;
snake.dx = 0;
snake.dy = grid;
// Ставим кубик в случайное место
cube.x = getRandomInt(0, 25) * grid;
cube.y = getRandomInt(0, 25) * grid;
}
}
});
}
Этап 4: Создаём управление стрелочками на клавиатуре
// Какие нажимаются клавиши и реагируем на них
document.addEventListener('keydown', function (e) {
// Проверка: если змейка движется, вверх, то нажатие вниз или вверх ничего не поменяет — змейка вверх
// Стрелка влево, если нажата стрелка влево, и при этом змейка не движется по горизонтали
if (e.which === 37 && snake.dx === 0) {
// то придаем ей движение по горизонтали, влево, а вертикальное — останавливаем, тоже самое и для остальных кнопках
snake.dx = -grid;
snake.dy = 0;
}
// Стрелка вверх
else if (e.which === 38 && snake.dy === 0) {
snake.dy = -grid;
snake.dx = 0;
}
// Стрелка вправо
else if (e.which === 39 && snake.dx === 0) {
snake.dx = grid;
snake.dy = 0;
}
// Стрелка вниз
else if (e.which === 40 && snake.dy === 0) {
snake.dy = grid;
snake.dx = 0;
}
});
Этап 5: Запускаем нашу игру, для этого достаточно запустить предыдущий бесконечный цикл, поэтому в конце добавляем
requestAnimationFrame(weblab);