Пишем игру “Змейка” на HTML и JavaScript: подробное руководство

Пишем игру “Змейка” на HTML и JavaScript: подробное руководство

Нажмите, чтобы оценить наш труд:
[Всего: 1 Средняя: 5]

Игра “Змейка” — это классическая аркадная игра, в которой игрок управляет змейкой, пытаясь собрать как можно больше пищи, чтобы увеличить длину змейки и заработать очки.

Описание: Создайте классическую игру Змейка на HTML5 с использованием JavaScript, CSS и аудио. Инструкция и пример кода для начинающих разработчиков.

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

Разберем подробно составление кода на HTML5 и JavaScript с нуля, расписывая каждый наш шаг, так сказать, “для чайников”. Но сначала покажем готовый результат.

Готовая игра

Поиграть в написанную нами ниже “Змейку” вы можете по ссылке на этом же сайте: игра “Змейка” Онлайн. Работает ТОЛЬКО на клавиатуре.

В коде реализованы возможности смены скорости игры, отключения звука и игнорирования границ поля (без столкновений); ведется подсчет очков. Управление – клавишами с клавиатуры: Вверх, Вниз, Влево, Вправо.

HTML-часть

Здесь мы создадим наш “каркас” веб-страницы, это все то, что мы видим:

<!DOCTYPE html>

Эта строка указывает браузеру на тип документа. <!DOCTYPE html> сообщает браузеру, что документ является HTML5 документом.

<html lang="ru">

Открывающий тег <html> указывает начало HTML документа. Атрибут lang="ru" указывает на язык документа, в данном случае, русский.

<head>

Открывающий тег <head> определяет начало секции заголовка документа. Здесь располагаются метаинформация, стили, скрипты и другие элементы, не отображаемые на странице.

<meta charset="UTF-8">

Элемент <meta> используется для установки метаданных, в данном случае, для указания кодировки символов документа, UTF-8 поддерживает различные языки, включая русский.

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Этот <meta> элемент используется для настройки отображения страницы на мобильных устройствах. Атрибут content="width=device-width, initial-scale=1.0" указывает браузеру использовать ширину экрана устройства и начальный масштаб 1:1.

<meta http-equiv="X-UA-Compatible" content="ie=edge">

Этот <meta> элемент устанавливает совместимость браузера с Internet Explorer и указывает использовать последний доступный режим IE.

<title>Игра змейка онлайн</title>

Элемент <title> устанавливает заголовок страницы, который отображается во вкладке браузера или при сохранении страницы в закладках, а также выводится  в виде названия страницы в поисковой выдаче.

<meta name="description" content="">

Этот <meta> элемент предназначен для описания содержимого страницы для поисковых систем. Содержимое атрибута content обычно содержит краткое описание страницы.

<meta name="robots" content="index, follow">

Этот <meta> элемент указывает поисковым роботам, следует ли индексировать (index) и следовать по ссылкам (follow) на данной странице.

<meta name="robots" content="noarchive">

Этот <meta> элемент указывает поисковым системам не кешировать содержимое страницы (noarchive), то есть не сохранять её в качестве архива.

<meta name="author" content="Poznayu.Com">

Этот <meta> элемент содержит информацию о авторе страницы. В данном случае, “Poznayu.Com” указывает на авторство содержимого.

<link rel="stylesheet" href="styles.css">

Элемент <link> используется для подключения внешних стилей CSS к HTML документу. Атрибут href указывает на путь к файлу стилей.

<link rel="icon" href="favicon.ico" type="image/x-icon">

Этот <link> элемент устанавливает иконку (favicon), отображаемую во вкладке браузера или на рабочем столе, если пользователь сохраняет ссылку.

<script src="script.js" defer></script>

Элемент <script> используется для подключения внешних скриптов JavaScript к HTML документу. Атрибут src указывает на путь к файлу скрипта, defer указывает на отложенную загрузку скрипта после загрузки контента страницы.

</head>

<body>

Закрывающий тег </head> завершает секцию заголовка документа, начатую ранее. Открывающий тег <body> определяет начало секции тела документа, где располагается основное содержимое страницы, видимое для пользователей.

<header>
<!-- Верхняя часть страницы, например, навигационное меню -->
</header>

Этот код создает секцию <header>, которая представляет собой верхнюю часть страницы. Как уже указано в комментарии в коде, здесь обычно располагается навигационное меню или другие элементы, отображаемые вверху страницы.

<main>

Открывающий тег <main> определяет главное содержимое страницы, которое содержит основную информацию, предназначенную для отображения пользователю.

<h1>Игра змейка онлайн</h1>

Элемент <h1> используется для создания заголовка верхнего уровня на странице. В данном случае, текст “Игра змейка онлайн” будет отображаться как основной заголовок страницы.

<audio id="eatSound" volume="0.3">
<source src="eat.wav" type="audio/mpeg">
Ваш браузер не поддерживает аудио элементы.
</audio>

Нам нужно, чтобы когда Змейка ела очередную точку, воспроизводился бы звук. Этот блок кода создает элемент <audio>, который позволяет воспроизводить звуковой файл на веб-странице. Атрибут id="eatSound" задает идентификатор для элемента, который может быть использован для управления им с помощью JavaScript. Атрибут volume="0.3" устанавливает начальную громкость звука. Внутри тега <audio> размещены один или несколько элементов <source>, которые определяют источники аудиофайла. В данном примере (но вы можете использовать любой звук) это файл eat.wav. Если браузер не поддерживает указанный формат аудио или не может воспроизвести звук, он отобразит текст “Ваш браузер не поддерживает аудио элементы.”

<div id="gameContainer">

Этот тег <div> с идентификатором gameContainer создает контейнер, который, в данном случае, содержит игровой интерфейс и элементы. Этот блок кода создает основной интерфейс игры, включая элементы управления, информацию о состоянии игры и игровое поле на холсте <canvas>.

<div id="gameInfo">
<p id="score">Очки: 0</p>
<p id="gameOver" style="margin-left: 10px;"></p>
</div>

Этот блок <div> с идентификатором gameInfo содержит, в данном случае, информацию об игре. Внутри него размещены два <p> элемента:

  • <p id="score">Очки: 0</p> отображает текущие очки игрока.
  • <p id="gameOver" style="margin-left: 10px;"></p> предназначен для отображения информации о завершении игры (например, “Game Over”), с отступом слева в 10 пикселей.
<canvas id="gameCanvas" width="400" height="400"></canvas>

Этот <canvas> элемент создает холст для рисования игрового поля. Атрибуты width="400" и height="400" задают его размеры в пикселях (400×400).

<div class="options">
<label for="speed">Скорость:</label>
<select id="speed" onchange="changeSpeed()">
<option value="150">Медленно</option>
<option value="100">Средне</option>
<option value="70">Быстро</option>
</select>
<input type="checkbox" id="ignoreEdgesCheckbox" onchange="toggleIgnoreEdges()">
<label for="ignoreEdgesCheckbox">Игнорировать границы</label>
<input type="checkbox" id="muteSoundCheckbox" onchange="toggleSound()">
<label for="muteSoundCheckbox">Отключить звук</label>
</div>

Этот блок <div> с классом options содержит различные настройки игры, которые будут переданы и использованы в нашем скрипте JavaScript:

  • <label for="speed">Скорость:</label> сопровождает выпадающий список <select> для выбора скорости игры.
  • <select id="speed" onchange="changeSpeed()"> определяет выпадающий список с идентификатором speed, который вызывает функцию changeSpeed() при изменении выбора.
  • <input type="checkbox" id="ignoreEdgesCheckbox" onchange="toggleIgnoreEdges()"> создает флажок для игнорирования границ игрового поля, вызывая функцию toggleIgnoreEdges() при изменении состояния.
  • <input type="checkbox" id="muteSoundCheckbox" onchange="toggleSound()"> создает флажок для отключения звука, вызывая функцию toggleSound() при изменении состояния.
<br>
<button type="button" onclick="startGame()">Начать игру</button>
<button onclick="restartGame()">Перезагрузить</button>
</div>

Эти строки содержат кнопки для управления игрой:

  • <br> добавляет пустой разрыв строки.
  • <button type="button" onclick="startGame()">Начать игру</button> создает кнопку для запуска игры, которая вызывает функцию startGame() при нажатии.
  • <button onclick="restartGame()">Перезагрузить</button> создает кнопку для перезагрузки игры, вызывая функцию restartGame() при нажатии.
</main>

<footer>
<!-- Нижняя часть страницы, например, контактная информация или ссылки -->
</footer>

</body>
</html>

Закрывающий тег </main> завершает секцию главного содержимого страницы, начатую ранее с <main>.

Тег <footer> определяет нижнюю часть страницы, где обычно размещается контактная информация, ссылки на социальные сети или другие важные детали.

Закрывающие теги </body> и </html> завершают тело HTML документа и сам HTML документ соответственно. Все содержимое страницы находится между открывающим и закрывающим тегами <html>.

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

Полная версия HTML-части нашей страницы с игрой “Змейка”:

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Игра змейка онлайн</title>
<meta name="description" content="">
<meta name="robots" content="index, follow">
<meta name="robots" content="noarchive">
<meta name="author" content="Poznayu.Com">
<link rel="stylesheet" href="styles.css">
<link rel="icon" href="favicon.ico" type="image/x-icon">
<script src="script.js" defer></script>
</head>

<body>
<header>
<!-- Верхняя часть страницы, например, навигационное меню -->
</header>

<main>
<h1>Игра змейка онлайн</h1>

<audio id="eatSound" volume="0.3">
<source src="eat.wav" type="audio/mpeg">
Ваш браузер не поддерживает аудио элементы.
</audio>

<div id="gameContainer">

<div id="gameInfo">
<p id="score">Очки: 0</p>
<p id="gameOver" style="margin-left: 10px;"></p>
</div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div class="options">
<label for="speed">Скорость:</label>
<select id="speed" onchange="changeSpeed()">
<option value="150">Медленно</option>
<option value="100">Средне</option>
<option value="70">Быстро</option>
</select>
<input type="checkbox" id="ignoreEdgesCheckbox" onchange="toggleIgnoreEdges()">
<label for="ignoreEdgesCheckbox">Игнорировать границы</label>
<input type="checkbox" id="muteSoundCheckbox" onchange="toggleSound()">
<label for="muteSoundCheckbox">Отключить звук</label>

</div>

<br>
<button type="button" onclick="startGame()">Начать игру</button>
<button onclick="restartGame()">Перезагрузить</button>

</div>

</main>

<footer>
<!-- Нижняя часть страницы, например, контактная информация или ссылки -->
</footer>

</body>
</html>

CSS-часть

Чтобы придать вид HTML-коду используются Каскадные Таблицы Стилей (CSS).

Рассмотрим нашу CSS-часть. Напомним, что мы вложили наши стили в виде отдельного CSS файла styles.css, хотя можно их прописать непосредственно в HTML, но это не является хорошим тоном:

<link rel="stylesheet" href="styles.css">

Далее разберем наш CSS файл.

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

body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
  • display: flex; – применяет Flexbox для макета страницы, делая контейнер гибким.
  • justify-content: center; – центрирует содержимое контейнера по горизонтали.
  • align-items: center; – центрирует содержимое контейнера по вертикали.
  • height: 100vh; – задает высоту контейнера в 100% высоты видимого окна браузера.
  • margin: 0; – убирает отступы вокруг контейнера.
#gameContainer {
text-align: center;
}
  • #gameContainer – стилизует элемент с id gameContainer.
  • text-align: center; – выравнивает текст внутри контейнера по центру.
#gameTitle {
margin-bottom: 10px;
}
  • #gameTitle – стилизует элемент с id gameTitle.
  • margin-bottom: 10px; – добавляет нижний отступ в 10 пикселей.
#gameInfo {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-bottom: 10px;
}
  • #gameInfo – стилизует элемент с id gameInfo.
  • display: flex; – применяет Flexbox для макета.
  • justify-content: center; – центрирует содержимое по горизонтали.
  • align-items: center; – центрирует содержимое по вертикали.
  • flex-direction: column; – размещает дочерние элементы в колонку.
  • margin-bottom: 10px; – добавляет нижний отступ в 10 пикселей.
#gameInfo p {
margin: 0;
color: red;
font-weight: bold;
}
  • #gameInfo p – стилизует все абзацы <p> элементы внутри #gameInfo.
  • margin: 0; – убирает отступы вокруг абзацев.
  • color: red; – устанавливает красный цвет текста.
  • font-weight: bold; – делает текст жирным.
#gameCanvas {
border: 1px solid black;
}
  • #gameCanvas – стилизует элемент с id gameCanvas.
  • border: 1px solid black; – устанавливает черную рамку толщиной в 1 пиксель.
.options {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-top: 10px;
}
  • .options – стилизует элементы с классом options.
  • display: flex; – применяет Flexbox для макета.
  • flex-direction: row; – размещает дочерние элементы в строку.
  • justify-content: center; – центрирует содержимое по горизонтали.
  • align-items: center; – центрирует содержимое по вертикали.
  • margin-top: 10px; – добавляет верхний отступ в 10 пикселей.
.options label,
.options select,
.options input[type="checkbox"] {
margin-right: 10px;
}
  • .options label, .options select, .options input[type="checkbox"] – стилизует <label>, <select> и <input type="checkbox"> элементы внутри .options.
  • margin-right: 10px; – добавляет правый отступ в 10 пикселей для всех перечисленных элементов.

Полная версия CSS-части нашей страницы с игрой “Змейка”:

body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
#gameContainer {
text-align: center;
}
#gameTitle {
margin-bottom: 10px;
}
#gameInfo {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
margin-bottom: 10px;
}
#gameInfo p {
margin: 0;
color: red;
font-weight: bold;
}
#gameCanvas {
border: 1px solid black;
}
.options {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
margin-top: 10px;
}
.options label,
.options select,
.options input[type="checkbox"] {
margin-right: 10px;
}

JavaScript код – программирование игры

Здесь, собственно, и происходит непосредственное написание программы игры “Змейка” – логики, управления, правил игры и всего прочего. Это самая основная и сложная часть для начинающих веб-программистов.

Опять же напомним, что мы подключаем наш JS скрипт в виде отдельного JavaScript файла – script.js. Его можно было прописать в самом HTML коде, но это не является хорошим тоном:

<script src="script.js" defer></script>

Этот код включает в себя начальные установки для игры “Змейка”, такие как определение канваса, контекста рисования, звуков, инициализация переменных и функции для воспроизведения звуков, генерации случайных чисел и создания еды:

const canvas = document.getElementById('gameCanvas');

Используется для получения элемента <canvas> с id gameCanvas и присваивает его константе canvas.

const ctx = canvas.getContext('2d');

Получает 2D контекст рисования для элемента <canvas> и присваивает его константе ctx. Этот контекст используется для рисования на канвасе.

const eatSound = document.getElementById('eatSound');

Получает аудио элемент с id eatSound и присваивает его константе eatSound.

const tileSize = 20;

Задает размер одной плитки игрового поля (20 пикселей).

const tileCount = canvas.width / tileSize;

Определяет количество плиток по горизонтали и вертикали, деля ширину канваса на размер плитки.

let snake = [];

let food = { x: 0, y: 0 };

Сначала инициализирует пустой массив для хранения координат частей змейки. Затем инициализирует объект food с начальными координатами (0, 0).

let dx = 1;

let dy = 0;

Устанавливает горизонтальное смещение змейки (движение вправо) и вертикальное смещение змейки (не движется по вертикали).

let score = 0;

Инициализирует счет игры с нуля.

let speed = 150; // Slow by default

Устанавливает начальную скорость игры (150 мс между кадрами).

let ignoreEdges = false;

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

let gameLoop;

Переменная для хранения идентификатора игрового цикла (таймера).

function playEatSound() {
eatSound.currentTime = 0;
eatSound.play();
}

Функция для воспроизведения звука еды. Устанавливает текущее время аудио на 0 и воспроизводит звук.

function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

Функция для получения случайного целого числа между min и max включительно.

function createFood() {
food.x = getRandomInt(0, tileCount - 1) * tileSize;
food.y = getRandomInt(0, tileCount - 1) * tileSize;
}

Функция для создания еды (точек) в случайной позиции на игровом поле. Генерирует случайные координаты для еды в пределах размеров игрового поля.

function drawSnake() {
snake.forEach((segment, index) => {
ctx.fillStyle = index === 0 ? 'purple' : 'green'; // Голова змеи фиолетовая
ctx.fillRect(segment.x, segment.y, tileSize, tileSize);
});
}
  • function drawSnake() { ... } – определяет функцию drawSnake, которая рисует змейку на канвасе.
  • snake.forEach((segment, index) => { ... }); – проходит по каждому сегменту змейки и его индексу в массиве snake.
  • ctx.fillStyle = index === 0 ? 'purple' : 'green'; – устанавливает цвет заполнения для головы змейки фиолетовый (purple), а для остальных сегментов зеленый (green).
  • ctx.fillRect(segment.x, segment.y, tileSize, tileSize); – рисует каждый сегмент змейки в виде прямоугольника на канвасе.
function drawFood() {
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, tileSize, tileSize);
}
  • function drawFood() { ... } – определяет функцию drawFood, которая рисует еду на канвасе.
  • ctx.fillStyle = 'red'; – устанавливает цвет заполнения для еды красный (red).
  • ctx.fillRect(food.x, food.y, tileSize, tileSize); – рисует еду в виде прямоугольника на канвасе по координатам food.x и food.y.

Этот код управляет движением змейки, обновляет ее положение на экране и обрабатывает события столкновения с едой или границами игрового поля:

function moveSnake() {

const head = { x: snake[0].x + dx * tileSize, y: snake[0].y + dy * tileSize }; 
snake.unshift(head);

if (head.x === food.x && head.y === food.y) { score++;
createFood(); playEatSound(); 
} else { snake.pop(); }

if (ignoreEdges) {
if (head.x >= canvas.width) head.x = 0; 
if (head.x < 0) head.x = canvas.width - tileSize; 
if (head.y >= canvas.height) head.y = 0; 
if (head.y < 0) head.y = canvas.height - tileSize; } 
else {
if (head.x >= canvas.width || head.x < 0 || head.y >= canvas.height || head.y < 0) {
clearInterval(gameLoop); document.getElementById('gameOver').innerText = 'Игра окончена!'; 
return; 
} 
} 
}
  • function moveSnake() { ... } – определяет функцию moveSnake, которая обновляет положение змейки.
  • const head = { x: snake[0].x + dx * tileSize, y: snake[0].y + dy * tileSize }; – создает новый сегмент для головы змейки, смещенный на один шаг в направлении движения.
  • snake.unshift(head); – добавляет новый сегмент головы в начало массива snake.
  • if (head.x === food.x && head.y === food.y) { ... } – проверяет, совпадает ли положение головы змейки с положением еды.
    • score++; – увеличивает счет на 1.
    • createFood(); – создает новую еду.
    • playEatSound(); – воспроизводит звук еды.
  • else { snake.pop(); } – если голова змейки не на позиции еды, удаляет последний сегмент змейки, чтобы сохранить длину постоянной.
  • if (ignoreEdges) { ... } – если границы игрового поля игнорируются, перемещает голову змейки на противоположную сторону при выходе за границу.
  • else { ... } – если границы игрового поля не игнорируются:
    • if (head.x >= canvas.width || head.x < 0 || head.y >= canvas.height || head.y < 0) { ... } – проверяет, вышла ли голова змейки за границы поля.
    • clearInterval(gameLoop); – останавливает игровой цикл.
    • document.getElementById('gameOver').innerText = 'Игра окончена!'; – отображает сообщение об окончании игры.
    • return; – завершает выполнение функции.

Этот код включает функции для управления скоростью игры, переключения режима игнорирования границ, обновления состояния игры и отрисовки элементов на канвасе:

function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
  • function clearCanvas() { ... } – определяет функцию clearCanvas, которая очищает канвас.
  • ctx.clearRect(0, 0, canvas.width, canvas.height); – очищает прямоугольную область от (0, 0) до (canvas.width, canvas.height).
function draw() {
clearCanvas();
drawSnake();
drawFood();
document.getElementById('score').innerText = 'Очки: ' + score;
}
  • function draw() { ... } – определяет функцию draw, которая отвечает за отрисовку элементов игры.
  • clearCanvas(); – очищает канвас перед каждой новой отрисовкой.
  • drawSnake(); – рисует змейку.
  • drawFood(); – рисует еду.
  • document.getElementById('score').innerText = 'Очки: ' + score; – обновляет текстовое значение элемента с id score, отображая текущий счет.
function update() {
moveSnake();
draw();
}
  • function update() { ... } – определяет функцию update, которая обновляет состояние игры.
  • moveSnake(); – обновляет положение змейки.
  • draw(); – рисует обновленные элементы игры на канвасе.
function changeSpeed() {
speed = parseInt(document.getElementById('speed').value);
clearInterval(gameLoop);
gameLoop = setInterval(update, speed);
}
  • function changeSpeed() { ... } – определяет функцию changeSpeed, которая изменяет скорость игры.
  • speed = parseInt(document.getElementById('speed').value); – получает новое значение скорости из выпадающего списка и преобразует его в целое число.
  • clearInterval(gameLoop); – останавливает текущий игровой цикл.
  • gameLoop = setInterval(update, speed); – запускает новый игровой цикл с обновленной скоростью.
function toggleIgnoreEdges() {
ignoreEdges = document.getElementById('ignoreEdgesCheckbox').checked;
}
  • function toggleIgnoreEdges() { ... } – определяет функцию toggleIgnoreEdges, которая переключает режим игнорирования границ игрового поля.
  • ignoreEdges = document.getElementById('ignoreEdgesCheckbox').checked; – устанавливает значение ignoreEdges в соответствии с состоянием флажка ignoreEdgesCheckbox.

И заключительная часть JS кода. Этот код завершает игру, предоставляя функции для перезапуска и начала игры, а также управление направлением движения змейки с помощью клавиш стрелок. Он также добавляет возможность отключения звука:

function restartGame() {
snake = [];
dx = 1;
dy = 0;
score = 0;
clearInterval(gameLoop);
snake.push({ x: 10 * tileSize, y: 10 * tileSize });
createFood();
document.getElementById('gameOver').innerText = '';
gameLoop = setInterval(update, speed);
}
  • function restartGame() { ... } – определяет функцию restartGame, которая перезапускает игру.
  • snake = []; – очищает массив змейки.
  • dx = 1; dy = 0; – устанавливает начальное направление движения змейки (вправо).
  • score = 0; – сбрасывает счет.
  • clearInterval(gameLoop); – останавливает текущий игровой цикл.
  • snake.push({ x: 10 * tileSize, y: 10 * tileSize }); – добавляет голову змейки в начальную позицию.
  • createFood(); – создает новое положение еды.
  • document.getElementById('gameOver').innerText = ''; – очищает текст “Игра окончена”.
  • gameLoop = setInterval(update, speed); – запускает новый игровой цикл с текущей скоростью.
function startGame() {
snake = [];
dx = 1;
dy = 0;
score = 0;
clearInterval(gameLoop);
snake.push({ x: 10 * tileSize, y: 10 * tileSize });
createFood();
document.getElementById('gameOver').innerText = '';
gameLoop = setInterval(update, speed);
}

function startGame() { ... } – определяет функцию startGame, которая запускает игру с нуля (идентична restartGame).

document.addEventListener('keydown', (event) => {
if (event.key === 'ArrowUp' && dy === 0) {
dx = 0;
dy = -1;
} else if (event.key === 'ArrowDown' && dy === 0) {
dx = 0;
dy = 1;
} else if (event.key === 'ArrowLeft' && dx === 0) {
dx = -1;
dy = 0;
} else if (event.key === 'ArrowRight' && dx === 0) {
dx = 1;
dy = 0;
}
});
  • document.addEventListener('keydown', (event) => { ... }); – добавляет обработчик события нажатия клавиши.
  • if (event.key === 'ArrowUp' && dy === 0) { ... } – проверяет, если нажата клавиша “вверх” и змейка не движется по вертикали, меняет направление на вверх.
  • else if (event.key === 'ArrowDown' && dy === 0) { ... } – проверяет, если нажата клавиша “вниз” и змейка не движется по вертикали, меняет направление на вниз.
  • else if (event.key === 'ArrowLeft' && dx === 0) { ... } – проверяет, если нажата клавиша “влево” и змейка не движется по горизонтали, меняет направление на влево.
  • else if (event.key === 'ArrowRight' && dx === 0) { ... } – проверяет, если нажата клавиша “вправо” и змейка не движется по горизонтали, меняет направление на вправо.
function toggleSound() {
eatSound.muted = document.getElementById('muteSoundCheckbox').checked;
}
  • function toggleSound() { ... } – определяет функцию toggleSound, которая переключает звук.
  • eatSound.muted = document.getElementById('muteSoundCheckbox').checked; – устанавливает значение muted для eatSound в соответствии с состоянием флажка muteSoundCheckbox.

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

Итак, вот полная версия JavaScript файла для нашей игры “Змейка”:

const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const eatSound = document.getElementById('eatSound');/* Your code... */
const tileSize = 20;
const tileCount = canvas.width / tileSize;

let snake = [];
let food = { x: 0, y: 0 };
let dx = 1;
let dy = 0;
let score = 0;
let speed = 150; // Slow by default
let ignoreEdges = false;
let gameLoop;

function playEatSound() {
eatSound.currentTime = 0;
eatSound.play();
}

function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}

function createFood() {
food.x = getRandomInt(0, tileCount - 1) * tileSize;
food.y = getRandomInt(0, tileCount - 1) * tileSize;
}

function drawSnake() {
snake.forEach((segment, index) => {
ctx.fillStyle = index === 0 ? 'purple' : 'green'; // Голова змеи фиолетовая
ctx.fillRect(segment.x, segment.y, tileSize, tileSize);
});
}

function drawFood() {
ctx.fillStyle = 'red';
ctx.fillRect(food.x, food.y, tileSize, tileSize);
}

function moveSnake() {
const head = { x: snake[0].x + dx * tileSize, y: snake[0].y + dy * tileSize };
snake.unshift(head);

if (head.x === food.x && head.y === food.y) {
score++;
createFood();
playEatSound();
} else {
snake.pop();
}

if (ignoreEdges) {
if (head.x >= canvas.width) head.x = 0;
if (head.x < 0) head.x = canvas.width - tileSize;
if (head.y >= canvas.height) head.y = 0;
if (head.y < 0) head.y = canvas.height - tileSize;
} else {
if (head.x >= canvas.width || head.x < 0 || head.y >= canvas.height || head.y < 0) {
clearInterval(gameLoop);
document.getElementById('gameOver').innerText = 'Игра окончена!';
return;
}
}

}

function clearCanvas() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}

function draw() {
clearCanvas();
drawSnake();
drawFood();
document.getElementById('score').innerText = 'Очки: ' + score;
}

function update() {
moveSnake();
draw();
}

function changeSpeed() {
speed = parseInt(document.getElementById('speed').value);
clearInterval(gameLoop);
gameLoop = setInterval(update, speed);
}

function toggleIgnoreEdges() {
ignoreEdges = document.getElementById('ignoreEdgesCheckbox').checked;
}

function restartGame() {
snake = [];
dx = 1;
dy = 0;
score = 0;
clearInterval(gameLoop);
snake.push({ x: 10 * tileSize, y: 10 * tileSize });
createFood();
document.getElementById('gameOver').innerText = '';
gameLoop = setInterval(update, speed);
}

function startGame() {
snake = [];
dx = 1;
dy = 0;
score = 0;
clearInterval(gameLoop);
snake.push({ x: 10 * tileSize, y: 10 * tileSize });
createFood();
document.getElementById('gameOver').innerText = '';
gameLoop = setInterval(update, speed);
}

document.addEventListener('keydown', (event) => {
if (event.key === 'ArrowUp' && dy === 0) {
dx = 0;
dy = -1;
} else if (event.key === 'ArrowDown' && dy === 0) {
dx = 0;
dy = 1;
} else if (event.key === 'ArrowLeft' && dx === 0) {
dx = -1;
dy = 0;
} else if (event.key === 'ArrowRight' && dx === 0) {
dx = 1;
dy = 0;
}
});

function toggleSound() {
eatSound.muted = document.getElementById('muteSoundCheckbox').checked;
}
Нажмите, чтобы оценить наш труд:
[Всего: 1 Средняя: 5]
Traveller

Добро пожаловать на Poznayu.com! Меня зовут Александр, и я создал этот сайт, собрав команду профессионалов, чтобы делиться полезными сведениями, интересными фактами и глубокими обзорами на самые разные темы, написанными нашей же командой авторов. Мы стремимся сделать каждый день насыщенным новыми знаниями и открытиями.

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

Присоединяйтесь к нашему сообществу и узнавайте новое каждый день вместе с нами! Оставляйте свои комментарии под текстом, все поля не обязательны !

Оставьте комментарий

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


Срок проверки reCAPTCHA истек. Перезагрузите страницу.

О нас | Контакты


Прокрутить вверх