Как собрать простую Змейку на чистом JavaScript: пошаговый разбор для новичка без фреймворков
-
Представь, что ты только начинаешь с JavaScript и хочешь понять, как работают игры. Эта статья покажет, как собрать классическую Змейку на чистом JS с Canvas. Ты научишься рисовать, управлять объектами и запускать цикл - без лишних библиотек.
Такой проект поможет разобраться в основах: переменные, функции, события клавиш и отрисовка. За пару часов у тебя будет рабочая игра. Проблемы вроде ‘не двигается змейка’ или ‘сталкивается не там’ решатся сами, когда поймешь логику.
Готовим основу: HTML и CSS
Сначала создаем файл index.html - это каркас игры. Нам нужен тег canvas, как холст для рисования. Добавим счетчик очков и простые стили, чтобы поле выглядело аккуратно. Без этого JS нечем будет рисовать.
Canvas - это элемент, где JS рисует пиксели. Укажи ширину и высоту, например 400x400 пикселей. CSS сделает фон черным, рамку и центрирует все на странице. Это базовый шаг, но без него ничего не запустится.
Вот минимальный HTML:
<!DOCTYPE html> <html> <head> <title>Змейка</title> <style> body { background: #000; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; font-family: Arial; } canvas { border: 2px solid #fff; background: #111; } #score { color: #fff; font-size: 24px; position: absolute; top: 20px; } </style> </head> <body> <div id="score">Счет: 0</div> <canvas id="game" width="400" height="400"></canvas> <script src="script.js"></script> </body> </html>- Canvas - холст размером 400x400. JS будет чистить и рисовать на нем каждый кадр.
- Стили - черный фон, белая рамка. Flex центрирует игру.
- Счет - div сверху, обновляем текстом из JS.
Инициализируем игру в JavaScript
Теперь создай script.js. Первое - достаем canvas и контекст 2d. Это как кисть для рисования линий, кругов, квадратов. Определи размер клетки - скажем 20 пикселей, чтобы поле делилось на сетку.
Змейка - массив объектов с координатами x и y. Еда - случайная точка на поле. Переменные для направления, скорости и счета. Начни с пустой змейки в центре, добавь стартовую еду.
Пример кода инициализации:
const canvas = document.getElementById('game'); const ctx = canvas.getContext('2d'); const grid = 20; const scoreElement = document.getElementById('score'); let snake = [{x: 200, y: 200}]; let dx = grid; let dy = 0; let food = {x: 0, y: 0}; let score = 0; function randomFood() { food.x = Math.floor(Math.random() * (canvas.width / grid)) * grid; food.y = Math.floor(Math.random() * (canvas.height / grid)) * grid; } randomFood();- ctx - контекст для drawRect, fillRect и clearRect.
- snake - массив сегментов, первый - голова.
- dx, dy - скорость: grid вправо, 0 вниз.
- randomFood() - ставит еду на случайную клетку.
Управление и движение змейки
Добавь слушатель клавиш. Стрелки меняют dx и dy, но не позволяй поворот на 180 градусов - иначе змейка врежется в себя. Функция update двигает голову и добавляет новый сегмент.
Если голова на еде - счет++, новая еда, змейка растет. Иначе убирай хвост. Проверяй столкновения со стенами и собой. Это сердце логики игры.
Код для клавиш и update:
document.addEventListener('keydown', (e) => { if (e.key === 'ArrowLeft' && dx === 0) { dx = -grid; dy = 0; } if (e.key === 'ArrowUp' && dy === 0) { dx = 0; dy = -grid; } if (e.key === 'ArrowRight' && dx === 0) { dx = grid; dy = 0; } if (e.key === 'ArrowDown' && dy === 0) { dx = 0; dy = grid; } }); function update() { const head = {x: snake.x + dx, y: snake.y + dy}; snake.unshift(head); if (head.x === food.x && head.y === food.y) { score++; scoreElement.textContent = `Счет: ${score}`; randomFood(); } else { snake.pop(); } // Столкновения (упрощено) if (head.x < 0 || head.x >= canvas.width || head.y < 0 || head.y >= canvas.height) { location.reload(); // Перезапуск } for (let i = 1; i < snake.length; i++) { if (head.x === snake[i].x && head.y === snake[i].y) { location.reload(); } } }- keydown - меняет направление, проверка на разворот.
- unshift/pop - добавляет голову, убирает хвост.
- Столкновения - с краем или телом = reload.
Отрисовка и игровой цикл
Функция draw чистит canvas и рисует все. Змейка - зеленые квадраты, еда - красная. Используй fillStyle и fillRect. Главный цикл с requestAnimationFrame обновляет и рисует 10 раз в секунду.
Скорость регулируй счетчиком кадров. Это создает плавность без лагов. Запусти цикл сразу после инициализации.
Полный цикл:
let count = 0; function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = 'red'; ctx.fillRect(food.x, food.y, grid - 2, grid - 2); ctx.fillStyle = 'lime'; snake.forEach((part, i) => { ctx.fillRect(part.x, part.y, grid - 2, grid - 2); }); } function loop() { count++; if (count > 10) { update(); count = 0; } draw(); requestAnimationFrame(loop); } loop();Элемент Цвет Функция Еда red fillRect с отступом Змейка lime Цикл по сегментам Фон #111 clearRect каждый раз - clearRect - стирает кадр.
- requestAnimationFrame - ~60 FPS, но update реже.
- count - замедляет движение.
Что добавит твоей Змейке огонька
Собрал базовую версию? Теперь подумай о паузе на Space, уровнях скорости или лучшей графике. Можно хранить рекорд в localStorage. Это расширит проект без фреймворков.
Логика простая, но в ней все основы JS: циклы, объекты, события. Поэкспериментируй с размером grid или формами еды. Дальше - тетрис или платформер на тех же принципах.
Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.
Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.
С вашими комментариями этот пост мог бы стать ещё лучше 💗
Зарегистрироваться Войти© 2024 - 2026 ExLends, Inc. Все права защищены.