Как сделать игру полноценную змейка на javascript
Перейти к содержимому

Как сделать игру полноценную змейка на javascript

  • автор:

Создание игры «Змейка» на чистом JavaScript и HTML5

Создание игры

Змейка — классическая игра, которую мы знаем еще с давних времен. Мы представляем вам статью, в ходе которой мы создадим полноценную игру «Змейка» на чистом JavaScript и HTML5.

Для создания веб игр на языке JavaScript используется технология Canvas , которая позволяет выполнять JavaScript код в HTML5 документе. Вы можете более детально ознакомиться с этой технологией посмотрев видео ниже:

HTML страница может содержать классическую разметку, в которую необходимо вписать canvas для отображения игры внутри него. Пример кода:

      Игра на JavaScript    

Внутри этого файла мы подключаем скрипт «game.js«, который будет описывать весь функционал нашей игры.

JavaScript файл

Внутри JavaScript файла добавьте выборку канваса, а также укажите контекст игры.

var cvs = document.getElementById("canvas"); var ctx = cvs.getContext("2d");

Добавление изображений и аудио

Далее необходимо загрузить все основные изображения, которые будут использоваться в игре. Для этого используйте класс Image . Ниже вы можете скачать все необходимые картинки к игре.

Код добавления изображений и аудио в игру:

const ground = new Image(); // Создание объекта ground.src = "img/ground.png"; // Указываем нужное изображение const foodImg = new Image(); // Создание объекта foodImg.src = "img/food.png"; // Указываем нужное изображение

Рисование объектов

Чтобы нарисовать объекты, а также добавить функционал к игре необходимо прописать функцию, которая будет постоянно вызываться. Такую функцию вы можете назвать как вам будет угодно. Чтобы функция работала постоянно, вы можете запустите её выполнение через setInterval() .

function draw() < // Какой-либо код >let game = setInterval(draw, 100); // Вызов функции из вне

Весь код игры стоит помещать в этот метод, ведь в нем он будет постоянно обрабатываться и игра будет выглядеть живой и анимированной.

Чтобы отследить нажатие игрока на какую-либо клавишу, необходимо использовать отслеживание событий — addEventListener . К примеру, чтобы отследить нажатие на любую клавишу на клавиатуре надо прописать следующий код:

// При нажатии на какую-либо кнопку document.addEventListener("keydown", someMethod); // Вызывается метод someMethod function someMethod() < // Изменяем что-то в коде >

Видео урок

Это были лишь небольшие азы перед созданием самой игры. Предлагаем вам ознакомиться с большим видео уроком, в ходе которого вы создадите 2D игру «Змейка» на чистом JavaScript’е.

Полезные ссылки из видео:

  • Текстовый редактор Atom.io ;
  • Подбор иконок IconFinder ;
  • Хостинг компания Reg.ru .

Весь JS код игры

Ниже вы можете посмотреть на полностью весь код JavaScript файла, который был создан в ходе видео урока выше:

const canvas = document.getElementById("game"); const ctx = canvas.getContext("2d"); const ground = new Image(); ground.src = "img/ground.png"; const foodImg = new Image(); foodImg.src = "img/food.png"; let box = 32; let score = 0; let food = < x: Math.floor((Math.random() * 17 + 1)) * box, y: Math.floor((Math.random() * 15 + 3)) * box, >; let snake = []; snake[0] = < x: 9 * box, y: 10 * box >; document.addEventListener("keydown", direction); let dir; function direction(event) < if(event.keyCode == 37 && dir != "right") dir = "left"; else if(event.keyCode == 38 && dir != "down") dir = "up"; else if(event.keyCode == 39 && dir != "left") dir = "right"; else if(event.keyCode == 40 && dir != "up") dir = "down"; >function eatTail(head, arr) < for(let i = 0; i < arr.length; i++) < if(head.x == arr[i].x && head.y == arr[i].y) clearInterval(game); >> function drawGame() < ctx.drawImage(ground, 0, 0); ctx.drawImage(foodImg, food.x, food.y); for(let i = 0; i < snake.length; i++) < ctx.fillStyle = i == 0 ? "green" : "red"; ctx.fillRect(snake[i].x, snake[i].y, box, box); >ctx.fillStyle = "white"; ctx.font = "50px Arial"; ctx.fillText(score, box * 2.5, box * 1.7); let snakeX = snake[0].x; let snakeY = snake[0].y; if(snakeX == food.x && snakeY == food.y) < score++; food = < x: Math.floor((Math.random() * 17 + 1)) * box, y: Math.floor((Math.random() * 15 + 3)) * box, >; > else snake.pop(); if(snakeX < box || snakeX >box * 17 || snakeY < 3 * box || snakeY >box * 17) clearInterval(game); if(dir == "left") snakeX -= box; if(dir == "right") snakeX += box; if(dir == "up") snakeY -= box; if(dir == "down") snakeY += box; let newHead = < x: snakeX, y: snakeY >; eatTail(newHead, snake); snake.unshift(newHead); > let game = setInterval(drawGame, 100);

Также вы можете скачать весь проект целиком по этой ссылке .

Больше интересных новостей

9 способов испортить код. Избавляемся от вредных привычек

9 способов испортить код. Избавляемся от вредных привычек

10 важнейших языков программирования

10 важнейших языков программирования

12 навыков, которыми обязан обладать Frontend-разработчик

12 навыков, которыми обязан обладать Frontend-разработчик

Рекомендации Билл Гейтса: ТОП-5 книг к прочтению

Рекомендации Билл Гейтса: ТОП-5 книг к прочтению

Комментарии (4)

Саня 20 ноября 2023 в 09:47

А как сделать так, чтобы игра начиналась заново после проигрыша?

Михаил 27 марта 2023 в 11:53

а где файл со стилями

миша 05 мая 2023 в 18:18

зажми контрл и нажми на этот текст

Елена 03 августа 2022 в 13:28

Кирилл Михайлович 17 мая 2022 в 20:33

Создание игры «Змейка» на чистом JavaScript и HTML5

Создание игры

Змейка — классическая игра, которую мы знаем еще с давних времен. Мы представляем вам статью, в ходе которой мы создадим полноценную игру «Змейка» на чистом JavaScript и HTML5.

Для создания веб игр на языке JavaScript используется технология Canvas , которая позволяет выполнять JavaScript код в HTML5 документе. Вы можете более детально ознакомиться с этой технологией посмотрев видео ниже:

HTML страница может содержать классическую разметку, в которую необходимо вписать canvas для отображения игры внутри него. Пример кода:

      Игра на JavaScript    

Внутри этого файла мы подключаем скрипт «game.js«, который будет описывать весь функционал нашей игры.

JavaScript файл

Внутри JavaScript файла добавьте выборку канваса, а также укажите контекст игры.

var cvs = document.getElementById("canvas"); var ctx = cvs.getContext("2d");

Добавление изображений и аудио

Далее необходимо загрузить все основные изображения, которые будут использоваться в игре. Для этого используйте класс Image . Ниже вы можете скачать все необходимые картинки к игре.

Код добавления изображений и аудио в игру:

const ground = new Image(); // Создание объекта ground.src = "img/ground.png"; // Указываем нужное изображение const foodImg = new Image(); // Создание объекта foodImg.src = "img/food.png"; // Указываем нужное изображение

Рисование объектов

Чтобы нарисовать объекты, а также добавить функционал к игре необходимо прописать функцию, которая будет постоянно вызываться. Такую функцию вы можете назвать как вам будет угодно. Чтобы функция работала постоянно, вы можете запустите её выполнение через setInterval() .

function draw() < // Какой-либо код >let game = setInterval(draw, 100); // Вызов функции из вне

Весь код игры стоит помещать в этот метод, ведь в нем он будет постоянно обрабатываться и игра будет выглядеть живой и анимированной.

Чтобы отследить нажатие игрока на какую-либо клавишу, необходимо использовать отслеживание событий — addEventListener . К примеру, чтобы отследить нажатие на любую клавишу на клавиатуре надо прописать следующий код:

// При нажатии на какую-либо кнопку document.addEventListener("keydown", someMethod); // Вызывается метод someMethod function someMethod() < // Изменяем что-то в коде >

Видео урок

Это были лишь небольшие азы перед созданием самой игры. Предлагаем вам ознакомиться с большим видео уроком, в ходе которого вы создадите 2D игру «Змейка» на чистом JavaScript’е.

Полезные ссылки из видео:

  • Текстовый редактор Atom.io ;
  • Подбор иконок IconFinder ;
  • Хостинг компания Reg.ru .

Весь JS код игры

Ниже вы можете посмотреть на полностью весь код JavaScript файла, который был создан в ходе видео урока выше:

const canvas = document.getElementById("game"); const ctx = canvas.getContext("2d"); const ground = new Image(); ground.src = "img/ground.png"; const foodImg = new Image(); foodImg.src = "img/food.png"; let box = 32; let score = 0; let food = < x: Math.floor((Math.random() * 17 + 1)) * box, y: Math.floor((Math.random() * 15 + 3)) * box, >; let snake = []; snake[0] = < x: 9 * box, y: 10 * box >; document.addEventListener("keydown", direction); let dir; function direction(event) < if(event.keyCode == 37 && dir != "right") dir = "left"; else if(event.keyCode == 38 && dir != "down") dir = "up"; else if(event.keyCode == 39 && dir != "left") dir = "right"; else if(event.keyCode == 40 && dir != "up") dir = "down"; >function eatTail(head, arr) < for(let i = 0; i < arr.length; i++) < if(head.x == arr[i].x && head.y == arr[i].y) clearInterval(game); >> function drawGame() < ctx.drawImage(ground, 0, 0); ctx.drawImage(foodImg, food.x, food.y); for(let i = 0; i < snake.length; i++) < ctx.fillStyle = i == 0 ? "green" : "red"; ctx.fillRect(snake[i].x, snake[i].y, box, box); >ctx.fillStyle = "white"; ctx.font = "50px Arial"; ctx.fillText(score, box * 2.5, box * 1.7); let snakeX = snake[0].x; let snakeY = snake[0].y; if(snakeX == food.x && snakeY == food.y) < score++; food = < x: Math.floor((Math.random() * 17 + 1)) * box, y: Math.floor((Math.random() * 15 + 3)) * box, >; > else snake.pop(); if(snakeX < box || snakeX >box * 17 || snakeY < 3 * box || snakeY >box * 17) clearInterval(game); if(dir == "left") snakeX -= box; if(dir == "right") snakeX += box; if(dir == "up") snakeY -= box; if(dir == "down") snakeY += box; let newHead = < x: snakeX, y: snakeY >; eatTail(newHead, snake); snake.unshift(newHead); > let game = setInterval(drawGame, 100);

Также вы можете скачать весь проект целиком по этой ссылке .

Telegram group

Підписуйтесь на нашу групу в Телеграмі ����

Змейка

Для начала нам нужно создать игровое поле при помощи Canvas. Мы зададим размеры холста, а в стиле пропишем его настройки: цвет фона, тень и т.д.

Сценарий игры разместим в отдельном файле snake.js.

  canvas Canvas 

Подготовим холст к игре. Проведём его инициализацию в сценарии. И сразу создадим функцию, которая будет заниматься отрисовкой игры.

 const canvas = document.getElementById('board'); const context = canvas.getContext('2d'); function drawGame()

Закрасим игровое поле чёрным цветом через функцию clearScreen().

 function drawGame() < clearScreen(); >function clearScreen() < context.fillStyle = 'black'; context.fillRect(0, 0, canvas.clientWidth, canvas.clientHeight); >drawGame(); 

На данном этапе мы получили игровое поле чёрного цвета, на котором будет выводить игровые объекты.

Snake Board

Запустим игровой цикл.

 let speed = 7; // скорость обновления экрана function drawGame() < clearScreen(); setTimeout(drawGame, 1000 / speed); // обновляем экран 7 раз в секунду > 

Разобьём игровое поле на условные квадратики, по которым будет двигаться змейка. Размеры квадратов вычисляются динамически. В каждом ряду будет 20 квадратов.

 let tileCount = 20; let tileSize = canvas.clientWidth / tileCount - 2; 

Нарисуем змейку, точнее, пока только голову в центре игрового поля.

 // позиция головы змейки let headX = 10; let headY = 10; function drawSnake() < context.fillStyle = 'orange'; context.fillRect(headX * tileCount, headY * tileCount, tileSize, tileSize); >function drawGame() < clearScreen(); drawSnake(); setTimeout(drawGame, 1000 / speed); > 

Snake Head

Добавим управление змейкой через клавиши-стрелки.

 // слушатель нажатий клавиш document.body.addEventListener('keydown', keyDown); 

Создадим переменные для направления движения головы змейки и создадим функцию, которая будет задавать направление движения змейки после нажатий клавиш со стрелками. На основе этой информации мы можем вычислить позицию змейки

 // направление движения змейки по двум осям let xDirection = 0; let yDirection = 0; function keyDown(event) < // клавиша вверх if(event.keyCode == 38)< yDirection = -1; // двигаемся на квадратик вверх xDirection = 0; >// клавиша вниз if(event.keyCode == 40) < yDirection = 1; // на квадратик вниз xDirection = 0; >// клавиша влево if(event.keyCode == 37) < yDirection = 0; xDirection = -1; // на квадратик влево >// клавиша вправо if(event.keyCode == 39) < yDirection = 0; xDirection = 1; // на квадратик вправо >> function changeSnakePosition() < headX = headX + xDirection; headY = headY + yDirection; >function drawGame() < clearScreen(); drawSnake(); changeSnakePosition(); setTimeout(drawGame, 1000 / speed); // обновляем экран 7 раз в секунду > 

На данный момент змейка может двигаться в любую сторону, не обращая внимания на границы поля и на себя. В реальной игре такое недопустимо. Змейка не может идти в обратную сторону по себе и выходить за пределы поля (тут могут быть варианты, мы берём стандартный вариант).

Давайте ограничим движение змейки в обратную сторону на себя.

 function keyDown(event) < // клавиша вверх if(event.keyCode == 38)< if(yDirection == 1) return; // запрещаем двигаться на себя yDirection = -1; xDirection = 0; > // клавиша вниз if(event.keyCode == 40)< if(yDirection == -1) return; // запрещаем двигаться на себя yDirection = 1; xDirection = 0; > // клавиша влево if(event.keyCode == 37)< if(xDirection == 1) return; // запрещаем двигаться на себя yDirection = 0; xDirection = -1; > // клавиша вправо if(event.keyCode == 39)< if(xDirection == -1) return; // запрещаем двигаться на себя yDirection = 0; xDirection = 1; > > 

Яблоко

Нарисуем яблоко. Оно представляет собой квадратик поля красного цвета.

 // позиция яблока let appleX = 5; let appleY = 5; function drawApple() < context.fillStyle = 'red'; context.fillRect(appleX * tileCount, appleY * tileCount, tileSize, tileSize); >function drawGame() < clearScreen(); drawSnake(); changeSnakePosition(); drawApple(); setTimeout(drawGame, 1000 / speed); > 

Apple

Столкновения

Теперь нужно определять моменты столкновения головы змейки с яблоком, сравнивая их позиции.

 function checkCollision() < // если позиции яблока и головы змейки совпали if (appleX == headX && appleY == headY) < // выводим яблоко в случайном месте по горизонтали appleX = Math.floor(Math.random() * tileCount); // выводим яблоко в случайном месте по вертикали appleY = Math.floor(Math.random() * tileCount); >> function drawGame() < clearScreen(); drawSnake(); changeSnakePosition(); drawApple(); checkCollision(); setTimeout(drawGame, 1000 / speed); > 

Тело змейки

После каждого съеденного яблока змейка увеличивается. Нам понадобится массив, который будет содержать части змейки и переменная, которая будет отвечать за размер змейки. После каждого столкновения (змейка съела яблоко) увеличиваем размер змейки.

 // массив для частей змейки const snakeParts = []; // начальный размер змейки let tailLength = 2; function checkCollision() < if (appleX == headX && appleY == headY) < appleX = Math.floor(Math.random() * tileCount); appleY = Math.floor(Math.random() * tileCount); // увеличиваем размер змейки tailLength++; > > 

Нам понадобится класс, который будет содержать информацию о частях змейки.

 class snakePart < constructor(x, y) < this.x = x; this.y = y; >> 

В функции drawSnake() добавим новый код, который будет рисовать хвост змейки к её голове.

 function drawSnake() < context.fillStyle = 'green'; // проходим в цикле по массиву for (let i = 0; i < snakeParts.length; i++) < // рисуем хвост змейки в виде квадратика зелёного цвета let part = snakeParts[i] context.fillRect(part.x * tileCount, part.y * tileCount, tileSize, tileSize); >// добавляем квадратики к змейке через push snakeParts.push(new snakePart(headX, headY)); if (snakeParts.length > tailLength) < snakeParts.shift(); // убираем лишнее > context.fillStyle = 'orange'; context.fillRect(headX * tileCount, headY * tileCount, tileSize, tileSize); > 

Змейка ожила, она есть яблоки и растёт в размерах.

Snake

Счёт

За каждое яблоко начисляется очко. Будем выводить счёт в углу игрового поля.

 // счёт let score = 0; function drawScore() < context.fillStyle = 'white'; context.font = "10px verdana"; context.fillText("Счёт: " + score, canvas.clientWidth - 50, 10); >function checkCollision() < if (appleX == headX && appleY == headY) < appleX = Math.floor(Math.random() * tileCount); appleY = Math.floor(Math.random() * tileCount); tailLength++; // увеличиваем счёт score++; > > function drawGame() < clearScreen(); drawSnake(); changeSnakePosition(); drawApple(); checkCollision(); drawScore(); setTimeout(drawGame, 1000 / speed); > 

Score

Конец игры

Создадим функцию, которая будет отслеживать конец игры. Во-первых, это происходит во время столкновения со стеной, во-вторых, когда змейка кусает себя.

 function isGameOver() < let gameOver = false; // проверяем начало игры if (yDirection === 0 && xDirection === 0) < return false; >if (headX < 0) else if (headX === tileCount) else if (headY < 0) else if (headY === tileCount) //если змейка укусила себя for (let i = 0; i < snakeParts.length; i++) < let part = snakeParts[i]; if (part.x === headX && part.y === headY) < gameOver = true; break; >> // Выводим сообщение if (gameOver) < context.fillStyle = 'white'; context.font = "50px verdana"; context.fillText("Конец игры! ", canvas.clientWidth / 6.5, canvas.clientHeight / 2); >return gameOver; > function drawGame() < changeSnakePosition(); let result = isGameOver(); if (result) clearScreen(); drawSnake(); drawApple(); checkCollision(); drawScore(); setTimeout(drawGame, 1000 / speed); // обновляем экран 7 раз в секунду > 

Игра готова. Она ещё требует различных доработок, но в целом мы получили полноценную игру.

Пишем игру змейка с помощью JavaScript + Canvas

image

Доброго времени суток, друзья. Сейчас я постараюсь вам показать как можно написать игру Змейка. Конечно, не самым быстрым способом и не самым маленьким в плане количества строк кода, но по-моему самым понятным для начинающих разработчиков, как я. Статья написана для людей, желающих чуть-чуть познакомиться с элементом canvas и его простыми методами для работы с 2D графикой.

Напишем змейку в «старом» виде, без особо красивой графики — в виде кубиков. Но это только упростит понимание разработки. Ну что же, поехали!

Подготовка

Пожалуй, стоит вообще начать с подготовки к созданию игры и написанию кода. Мы будем использовать простой редактор Sublime Text. Впрочем, это не важно. Все делаем в одном документе, чтобы было быстрее.

Первым делом, напишем сам код для встраивания canvas в документ. Напомню, что canvas поддерживается только в HTML5.

 HTML5 не поддерживается 

Подготовка завершена, теперь мы можем приступать к созданию самой игры.

Начинаем

Для начала, я хотел бы вам вообще объяснить как будет работать змейка, так будет гораздо понятнее. Наша змейка — это массив. Массив элементов, элементы — это ее части, на которые она делиться. Это всего лишь квадратики, которые имеют координаты X и Y. Как вы знаете, X — горизонталь, Y — вертикаль. В обычном виде мы представляем себе координатную плоскость вот так:

image

Она абсолютно правильная, в этом нет сомнения, но на мониторе компьютера (в частности, canvas) она выглядит по-другому, вот так:

image

Это нужно знать, если вы вдруг в первый раз столкнулись с canvas. Я, когда столкнулся с этим, сначала вообще не понял где точка (0,0), благо я быстро разобрался. Надеюсь и у вас проблем не возникло.

Вернемся к элементам змейки, ее частям. Представим, что каждый элемент имеет свои координаты, но одинаковую высоту и одинаковую ширину. Это квадратики, не более. А теперь представим, что мы вот нарисовали змейку, все квадратики, они идут друг за другом, одинаковые такие. И тут мы решили, что нам нужно подвинуть змейку вправо. Как бы вы поступили?

Некоторые люди ответили бы, что нам нужно первый элемент подвинуть вправо, затем второй, затем третий и так далее. Но для меня этот вариант не является правильным, так как в случае, если вдруг змейка огромная, а компьютер слабый, мы можем заметить, что змейка иногда разрывается, что вообще не должно быть. Да и вообще, данный способ требует слишком много команд, когда можно обойтись гораздо меньшим количеством, не потеряв качество. А теперь мой способ: Мы берем последний элемент змейки, и ставим его в начало, изменяя его координаты так, чтобы он был после головы. Теперь этот элемент — голова. Всего-то! И да, эффект движения будет присутствовать, а на компьютере вообще не будет заметно, как мы спрятали хвост, а потом его поставили в начало. именно так мы и будем поступать во время создания движения змейки.

Вот тут точно начинаем

Сначала нам нужно объявить некоторые переменные, которые мы в дальнейшем будем использовать.

//Возвращает случайное число. function rand (min, max) //Функция для создания нового яблока. function newA () //Функция для создания тела змейки из одного элемента. function newB () ];> var gP = document.getElementById('gP'), //Достаем canvas. //Получаем "контекст" (методы для рисования в canvas). g = gP.getContext('2d'), sBody = null, //Тело змейки, мы потом его создадим. d = 1, //Направление змейки 1 - dправо, 2 - вниз 3 - влево, 4 - вверх. a = null, //Яблоко, массив, 0 элемент - x, 1 элемент - y. s = 30; newB(); newA(); //Создаем змейку. 

И так, вообще, нужно чуть-чуть пояснить зачем нам нужно в функции возвращения случайного числа, умножать и делить на переменную s, которая хранит в себе ни что иное, как ширину, по совместительству и высоту элементов змейки. На самом деле, это нужно, чтобы не было смещений во время движения, так как у нас ширина элемента — 30, то если мы хотим двигать ее без разрывов, то все координаты должны делиться на 30 без остатка. Именно поэтому я делю на число, округляю, а потом умножаю. Таким образом, число возвращается таким, что его можно разделить без остатка на 30.

Вы могли бы возразить, сказав, что ты мог бы просто холсту сделать ширину и высоту, кратную 30. Но на самом деле, это не лучший вариант. Так как я лично привык использовать всю ширину экрана. И в случае, если ширина = 320, то мне пришлось бы аж целых 20 пикселей забирать у пользователя, что могло бы доставить дискомфорт. Именно поэтому в нашей змейки все координаты объектов делятся на 30, чтобы не было никаких неожиданных моментов. Было бы даже правильнее вынести это как отдельную функцию, так как она достаточно часто используется в коде. Но к этому выводу я пришел поздно. (Но возможно это даже не нужно).

Теперь сделаем так, чтобы картинка имела четкое качество отображения. По ходу статьи, я буду дописывать код, в некоторых местах возвращаться к началу, так что при себе имейте полную картину кода.

gP.width = innerWidth; //Сохраняем четкость изображения, выставив полную ширину экрана. gP.height = innerHeight; //То же самое, но только с высотой. 

Если что, то переменные innerWidth и innerHeight хранятся в глобальном пространстве имен.
Поэтому к ним можно обратиться именно так. Правда, я не знаю правильно ли так делать.

Ну что же, теперь начинаем писать код змейки.

Чтобы было движение, нам нужна анимация, мы будем использовать функцию setInterval, вторым параметром которой будет число 60. Можно чуть больше, 75 на пример, но мне нравится 60. Функция всего на всего каждые 60 мс. рисует змейку «заново». Дальнейшее написание кода — это только этот интервал.

Покажу вообще простую отрисовку нашей змейки, пока что без движения.

setInterval(function()< g.clearRect(0,0,gP.width,gP.height); //Очищаем старое. g.fillStyle = "red"; //Даем красный цвет для рисования яблока. g.fillRect(. a, s, s); //Рисуем яблоко на холсте 30x30 с координатами a[0] и a[1]. g.fillStyle = "#000"; //А теперь черный цвет для змейки. >, 60); 

Чтобы проверить, что наша змейка не сталкивается сама с собой, нам нужно сделать некоторую проверку для каждого элемента, кроме последнего. Мы будем проверять, не равны ли координаты последнего элемента (головы) змейки любым из… То есть проще говоря: не произошло ли столкновение. Эта строчка кода была единой строкой, но вам сделал ее понятной. Напоминаю, что все это добавляется в функцию интервала.

 sBody.forEach(function(el, i)< //Проверка на то, что яблоко ушло за границы окна, мы его не можем увидеть. if (a[0] + s >= gP.width || a[1] + s >= gP.height) newA(); //Проверка на столкновение. var last = sBody.length - 1; if ( el.x == sBody[last].x && el.y == sBody[last].y && i < last) < sBody.splice(0,last); //Стираем тело змейки. sBody = []; //Создаем его заново. d = 1; //Меняем направление на правую сторону. > >); //+ // Сохраняем хвост и голову змейки. var m = sBody[0], f = , l = sBody[sBody.length - 1]; /* Далее мы создаем тот самый эффект движения. Напомню, что мы меняем координаты лишь хвоста, оставляя неподвижным остальную часть тела. Делается это путем проверки направления змейки (изначально - это 1, - право), а затем уже изменяем координаты. Соответственно, комментарии все описывают. */ //Если направление вправо, то тогда сохраняем Y, но меняем X на + s. if (d == 1) f.x = l.x + s, f.y = Math.round(l.y / s) * s; // Если направление вниз, то сохраняем X, но меняем Y на + s. if (d == 2) f.y = l.y + s, f.x = Math.round(l.x / s) * s; //Если направление влево, то сохраняем Y, но меняем X на -s. if (d == 3) f.x = l.x - s, f.y = Math.round(l.y / s) * s; //Если направление вверх, то сохраняем X, Но меняем Y на -s. if (d == 4) f.y = l.y - s, f.x = Math.round(l.x / s) * s; 

А теперь, вы наверное заметили, что во время того, как мы изменяем координаты, мы вечно что-то «сохраняем», сначала поделив, а потом округлив и умножив на число s. Это все тот же самый способ выравнивания змейки относительно яблока. Движение в данном случае строгое, простое, поэтому и есть змейка яблоко может строго по определенным правилам, которые задан в самом начале интервала. И если бы координаты головы змейки хоть на 1px сместились бы, то яблоко нельзя было бы съесть. И да, это простой вариант, поэтому все так сильно ограничено.

Ну а нам же осталось что сделать? Правильно, удалить из массива хвост (первый элемент), добавить новый элемент в самый конец и отрисовать всю змейку. Сделаем это, добавив в конец интервала вот такие строчки кода.

 sBody.push(f); //Добавляем хвост после головы с новыми координатами. sBody.splice(0,1); //Удаляем хвост. //Отрисовываем каждый элемент змейки. sBody.forEach(function(pob, i) < //Если мы двигаемся вправо, то если позиция элемента по X больше, чем ширина экрана, то ее надо обнулить if (d == 1) if (pob.x >Math.round(gP.width / s) * s) pob.x = 0; //Если мы двигаемся вниз, то если позиция элемента по X больше, чем высота экрана, то ее надо обнулить. if (d == 2) if (pob.y > Math.round(gP.height / s) * s) pob.y = 0; //Если мы двигаемся влево, и позиция по X меньше нуля, то мы ставим элемент в самый конец экрана (его ширина). if (d == 3) if (pob.x < 0) pob.x = Math.round(gP.width / s) * s; //Если мы двигаемся вверх, и позиция по Y меньше нуля, то мы ставим элемент в самый низ экрана (его высоту). if (d == 4) if (pob.y < 0) pob.y = Math.round(gP.height / s) * s; //И тут же проверка на то, что змейка съела яблоко. if (pob.x == a[0] && pob.y == a[1]) newA(), sBody.unshift() //А теперь рисуем элемент змейки. g.fillRect(pob.x, pob.y, s, s); >); 

В добавок к отрисовке змейки, я добавил код, который делает ощущение, что конец экрана — это его начало. И если змейка выходит за границы, то она потом выходит из начала, на погибая.
Вы можете заменить обнуление координат, на пример, на сбрасывание игры, если у вас все очень жестко. Но мне нравится больше так. Ну а теперь, осталось только по нажатию кнопок изменять направление змейки. Делает за считанные секунды. Нужно лишь написать этот код сразу после setInterval. Примерно так:

//setInerval(. ); onkeydown = function (e) < var k = e.keyCode; if ([38,39,40,37].indexOf(k) >= 0) e.preventDefault(); if (k == 39 && d != 3) d = 1; //Вправо if (k == 40 && d != 4) d = 2; //Вниз if (k == 37 && d != 1) d = 3; //Влево if (k == 38 && d != 2) d = 4; //Вверх >; 

Тут мы сделали так, что если змейка двигается вправо, то она не может изменить направление налево. Это логично, на самом деле.

Вот и все, друзья. Моя первая статья, написанная новичком для новичков. Надеюсь, все было понятно и кому-то это пригодилось. Змейку можно усовершенствовать, добавив на пример, счетчик очков, рекорды, дополнительные фишки, но это все уже дополнения, которые вы можете сделать сами. На этом все, всем удачи!

Посмотреть демонстрацию (CodePen):

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *