<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Как собрать простую Змейку на чистом JavaScript: пошаговый разбор для новичка без фреймворков]]></title><description><![CDATA[<p dir="auto">Представь, что ты только начинаешь с JavaScript и хочешь понять, как работают игры. Эта статья покажет, как собрать классическую Змейку на чистом JS с Canvas. Ты научишься рисовать, управлять объектами и запускать цикл - без лишних библиотек.</p>
<p dir="auto">Такой проект поможет разобраться в основах: переменные, функции, события клавиш и отрисовка. За пару часов у тебя будет рабочая игра. Проблемы вроде ‘не двигается змейка’ или ‘сталкивается не там’ решатся сами, когда поймешь логику.</p>
<h2>Готовим основу: HTML и CSS</h2>
<p dir="auto">Сначала создаем файл index.html - это каркас игры. Нам нужен тег canvas, как холст для рисования. Добавим счетчик очков и простые стили, чтобы поле выглядело аккуратно. Без этого JS нечем будет рисовать.</p>
<p dir="auto">Canvas - это элемент, где JS рисует пиксели. Укажи ширину и высоту, например 400x400 пикселей. CSS сделает фон черным, рамку и центрирует все на странице. Это базовый шаг, но без него ничего не запустится.</p>
<p dir="auto">Вот минимальный HTML:</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;Змейка&lt;/title&gt;
    &lt;style&gt;
        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; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div id="score"&gt;Счет: 0&lt;/div&gt;
    &lt;canvas id="game" width="400" height="400"&gt;&lt;/canvas&gt;
    &lt;script src="script.js"&gt;&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<ul>
<li><strong>Canvas</strong> - холст размером 400x400. JS будет чистить и рисовать на нем каждый кадр.</li>
<li><strong>Стили</strong> - черный фон, белая рамка. Flex центрирует игру.</li>
<li><strong>Счет</strong> - div сверху, обновляем текстом из JS.</li>
</ul>
<h2>Инициализируем игру в JavaScript</h2>
<p dir="auto">Теперь создай script.js. Первое - достаем canvas и контекст 2d. Это как кисть для рисования линий, кругов, квадратов. Определи размер клетки - скажем 20 пикселей, чтобы поле делилось на сетку.</p>
<p dir="auto">Змейка - массив объектов с координатами x и y. Еда - случайная точка на поле. Переменные для направления, скорости и счета. Начни с пустой змейки в центре, добавь стартовую еду.</p>
<p dir="auto">Пример кода инициализации:</p>
<pre><code class="language-javascript">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();
</code></pre>
<ul>
<li><strong>ctx</strong> - контекст для drawRect, fillRect и clearRect.</li>
<li><strong>snake</strong> - массив сегментов, первый - голова.</li>
<li><strong>dx, dy</strong> - скорость: grid вправо, 0 вниз.</li>
<li><strong>randomFood()</strong> - ставит еду на случайную клетку.</li>
</ul>
<h2>Управление и движение змейки</h2>
<p dir="auto">Добавь слушатель клавиш. Стрелки меняют dx и dy, но не позволяй поворот на 180 градусов - иначе змейка врежется в себя. Функция update двигает голову и добавляет новый сегмент.</p>
<p dir="auto">Если голова на еде - счет++, новая еда, змейка растет. Иначе убирай хвост. Проверяй столкновения со стенами и собой. Это сердце логики игры.</p>
<p dir="auto">Код для клавиш и update:</p>
<pre><code class="language-javascript">document.addEventListener('keydown', (e) =&gt; {
    if (e.key === 'ArrowLeft' &amp;&amp; dx === 0) { dx = -grid; dy = 0; }
    if (e.key === 'ArrowUp' &amp;&amp; dy === 0) { dx = 0; dy = -grid; }
    if (e.key === 'ArrowRight' &amp;&amp; dx === 0) { dx = grid; dy = 0; }
    if (e.key === 'ArrowDown' &amp;&amp; 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 &amp;&amp; head.y === food.y) {
        score++;
        scoreElement.textContent = `Счет: ${score}`;
        randomFood();
    } else {
        snake.pop();
    }
    // Столкновения (упрощено)
    if (head.x &lt; 0 || head.x &gt;= canvas.width || head.y &lt; 0 || head.y &gt;= canvas.height) {
        location.reload(); // Перезапуск
    }
    for (let i = 1; i &lt; snake.length; i++) {
        if (head.x === snake[i].x &amp;&amp; head.y === snake[i].y) {
            location.reload();
        }
    }
}
</code></pre>
<ul>
<li><strong>keydown</strong> - меняет направление, проверка на разворот.</li>
<li><strong>unshift/pop</strong> - добавляет голову, убирает хвост.</li>
<li><strong>Столкновения</strong> - с краем или телом = reload.</li>
</ul>
<h2>Отрисовка и игровой цикл</h2>
<p dir="auto">Функция draw чистит canvas и рисует все. Змейка - зеленые квадраты, еда - красная. Используй fillStyle и fillRect. Главный цикл с requestAnimationFrame обновляет и рисует 10 раз в секунду.</p>
<p dir="auto">Скорость регулируй счетчиком кадров. Это создает плавность без лагов. Запусти цикл сразу после инициализации.</p>
<p dir="auto">Полный цикл:</p>
<pre><code class="language-javascript">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) =&gt; {
        ctx.fillRect(part.x, part.y, grid - 2, grid - 2);
    });
}

function loop() {
    count++;
    if (count &gt; 10) {
        update();
        count = 0;
    }
    draw();
    requestAnimationFrame(loop);
}
loop();
</code></pre>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Элемент</th>
<th>Цвет</th>
<th>Функция</th>
</tr>
</thead>
<tbody>
<tr>
<td>Еда</td>
<td>red</td>
<td>fillRect с отступом</td>
</tr>
<tr>
<td>Змейка</td>
<td>lime</td>
<td>Цикл по сегментам</td>
</tr>
<tr>
<td>Фон</td>
<td>#111</td>
<td>clearRect каждый раз</td>
</tr>
</tbody>
</table>
<ul>
<li><strong>clearRect</strong> - стирает кадр.</li>
<li><strong>requestAnimationFrame</strong> - ~60 FPS, но update реже.</li>
<li><strong>count</strong> - замедляет движение.</li>
</ul>
<h2>Что добавит твоей Змейке огонька</h2>
<p dir="auto">Собрал базовую версию? Теперь подумай о паузе на Space, уровнях скорости или лучшей графике. Можно хранить рекорд в localStorage. Это расширит проект без фреймворков.</p>
<p dir="auto">Логика простая, но в ней все основы JS: циклы, объекты, события. Поэкспериментируй с размером grid или формами еды. Дальше - тетрис или платформер на тех же принципах.</p>
]]></description><link>https://forum.exlends.com/topic/2194/kak-sobrat-prostuyu-zmejku-na-chistom-javascript-poshagovyj-razbor-dlya-novichka-bez-frejmvorkov</link><generator>RSS for Node</generator><lastBuildDate>Mon, 27 Apr 2026 13:55:40 GMT</lastBuildDate><atom:link href="https://forum.exlends.com/topic/2194.rss" rel="self" type="application/rss+xml"/><pubDate>Mon, 27 Apr 2026 08:19:41 GMT</pubDate><ttl>60</ttl></channel></rss>