Ни для кого уже не секрет, что нейросети сегодня используются при разработке игр: создание концептов, арта, написание историй. А что насчет кодинга? Могут ли нейросети кодить вместо разработчиков и создавать полноценные игры? За ответом на этот вопрос я обратился к одной из лучших по мнению многих обзорщиков нейросетей для разработки – Qwen. Кстати, эта нейросеть бесплатна и без проблем работает в РФ.
Давайте начнем с простого. База для любого разработчика игр – аналог Pong! Но с небольшим усложнением. Мне захотелось, чтобы вместо шарика в игре летала снежинка. Я вбил самый простой промпт:
Напиши игру типа Pong! Вместо шарика сделай снежинку
В результате в течение 1 минуты нейросеть написала 475 строк кода и выдала мне саммари:
Это полноценная HTML-игра в стиле Pong с снежинкой! Основные особенности:
Вместо шарика используется анимированная снежинка с вращением
Стильный темный интерфейс с градиентами и свечением
Анимированный снег в фоне
Реалистичная физика отскоков
Подсчет очков до 5
Эффекты при отскоке (вращение снежинки)
Адаптивный дизайн
⌨️ Управление:
Игрок 1: W и S
Игрок 2: Стрелки вверх и вниз
? Особенности дизайна:
Градиентный фон с зимней тематикой
Анимированные снежинки в фоне
Свечение элементов
Плавные переходы и анимации
Экран окончания игры с кнопкой перезапуска
Игра полностью автономна и работает в любом современном браузере!

То есть, Qwen в действительности сделала даже больше, чем я просил. Нейронка добавила в игру фон со стильными снежинками и добавила в игру полноценный PVP режим. Хотя, режима PVE в игре не было. Справедливости ради, в этом моя вина – я подразумевал его наличие у себя в голове, но не написал об этом в промпте. Что ж, давайте исправим:
Я: Можешь добавить в игру PVE режим?
Qwen: Конечно! Вот обновлённая версия игры Snow Pong с режимом PVE (игрок против компьютера). Я добавил:
Кнопку выбора режима: PVP или PVE
В режиме PVE правая ракетка управляется ИИ
ИИ отслеживает положение снежинки с небольшой задержкой для реалистичности
Сохраняется вся графика и анимации
Далее ещё минута, ещё 544 строчки кода и перевод мной новая версия игры: теперь я могу выбрать режим игры: PVP или PVE. Выбираем игру против компьютера и… понимаем, что это слишком легко. Qwen пожалел нас и сделал ракетку ИИ-противника очень медленной. С такой скоростью он отражал только один удар из пяти. Хорошо, что вместе с этим он предложил:
Qwen: Хочешь добавить уровни сложности (лёгкий/средний/сложный ИИ)?
Я: Да, давай добавим уровни сложности
Новое минутное ожидание и еще 536 строчек кода и передо мной новая игра с уровнями сложности. И вместе с этим, новое предложение от ИИ:
Qwen: Хочешь добавить звуки или счётчик очков за сессию? ?
Я: Да, давай добавим звуки и счетчик очков за сессию, а так же переведем управление игрока в PVE режиме на стрелочки
Управление на W/S не всегда было удобно, так как эти символы не работали в верхнем регистре или в русской раскладке. Нейросеть в переписке со мной предлагала исправить эти проблемы, но я решил не зацикливаться на этом и просто перевести управление на стрелочки.
Итак, еще пару минут (по мере усложнения кода увеличивается и время ожидания) и 614 строчек кода спустя нас ждет новая версия игры. Новая версия оказалась проблемной – игра крашилась сразу же после запуска. После пары сообщений Qwen понял в чем была причина краша и исправил его. Но появилась новая проблема – теперь в PVE режиме ракетка игрока (на стрелочках) не двигалась. После недолгой переписки с ИИ мы решили проблему, на это ушло около пяти минут. Очень понравилась его решительность:
Я: Слушай, стрелочки все еще не работают Qwen: Спасибо, что держишь меня в курсе! Давай раз и навсегда решим проблему с управлением стрелочками
Раз и навсегда решить проблему со стрелочками не удалось, поэтому я предложил альтернативу – управление второго игрока на клавишах O и L. Таким образом в PVP режиме игрок 1 управлял на WS, а игрок 2 на OL, а в PVE режиме игрок управлял на WS.
До идеальной игры осталась последняя деталь: боты в PVE режиме были слишком слабы – даже сильный бот не создавал никаких проблем. Я попросил его повысить уровень сложности и увеличить скорость передвижения ракетки у ботов – и все сработало. Теперь чтобы победить сложного бота надо постараться. Игра полностью готова и любой желающий может в неё поиграть:
https://chat.qwen.ai/s/deploy/386f16fb-096d-4fe2-b706-a8c72374825c
Не знаю, как долго она будет храниться на серверах, поэтому не могу ручаться за работоспособность ссылки для тех, кто увидит статью сильно позже её выхода.



Что я получил в итоге?
Полноценный симулятор Pong! со снежинкой вместо мячика. На фоне падал снег, добавляя игре атмосферы. В игре присутствовал счетчик очков. Удары ракетки по мячику и победа озвучивались. В игре было два режима: PVP и PVE и три уровня сложности для PVE режима. Режим и сложность выбирались в главном меню игры. Нейросеть отлично запоминает что мы с ней делали и по моей просьбе легко достает нужную мне версию игры. Итоговый код игры составил 701 строчку. Его я приложу ниже. Отмечу также, что мне не пришлось применить никаких знаний программирования для создания этой игры. Все что я делал – это ставил задачи нейросети.
Что я потратил?
Примерно полтора часа времени на диалог с ИИ с учетом времени ожидания ответа. Нейросеть бесплатна и ничего от меня не потребовала.
Получается, что нейросети уже сейчас могут успешно генерировать простые игры типа Pong!, даже с небольшими усложнениями. Но, что будет, если попросить их создать что-то более сложное? В следующий раз мы с Qwen попробуем создать что-то посложнее понга. Например, платформер. И я обязательно напишу об этом.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Snow Pong</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Arial', sans-serif;
}
body {
background: linear-gradient(135deg, #1e3c72, #2a5298);
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
overflow: hidden;
}
.game-container {
position: relative;
width: 800px;
height: 600px;
background: rgba(10, 20, 40, 0.8);
border-radius: 20px;
box-shadow: 0 20px 50px rgba(0, 0, 0, 0.5);
overflow: hidden;
border: 2px solid rgba(255, 255, 255, 0.2);
}
.game-title {
text-align: center;
color: white;
padding: 20px;
font-size: 28px;
font-weight: bold;
text-shadow: 0 0 10px rgba(135, 206, 250, 0.8);
}
.score-board {
display: flex;
justify-content: space-around;
background: rgba(0, 0, 0, 0.3);
padding: 15px;
color: white;
font-size: 24px;
font-weight: bold;
}
.score {
text-shadow: 0 0 5px rgba(135, 206, 250, 0.8);
}
.session-score {
font-size: 16px;
color: rgba(255, 255, 255, 0.7);
margin-top: 5px;
text-align: center;
}
.paddle {
position: absolute;
width: 15px;
height: 100px;
background: linear-gradient(to right, #4facfe, #00f2fe);
border-radius: 10px;
box-shadow: 0 0 15px rgba(79, 172, 254, 0.6);
}
.left-paddle {
left: 30px;
}
.right-paddle {
right: 30px;
}
/* --- ДВОЙНОЙ КРЕСТ — СНЕЖИНКА (настоящая!) --- */
.snowflake {
position: absolute;
width: 6px;
height: 6px;
background: white;
border-radius: 50%;
transform: translate(-50%, -50%);
box-shadow:
/* Горизонтальные лучи (← и →) */
-15px 0 0 rgba(255, 255, 255, 0.9),
15px 0 0 rgba(255, 255, 255, 0.9),
/* Вертикальные лучи (↑ и ↓) */
0 -15px 0 rgba(255, 255, 255, 0.9),
0 15px 0 rgba(255, 255, 255, 0.9),
/* Диагональ ↖ и ↘ */
-11px -11px 0 rgba(255, 255, 255, 0.8),
11px 11px 0 rgba(255, 255, 255, 0.8),
/* Диагональ ↗ и ↙ */
11px -11px 0 rgba(255, 255, 255, 0.8),
-11px 11px 0 rgba(255, 255, 255, 0.8);
animation: rotate 8s linear infinite;
filter: drop-shadow(0 0 2px rgba(255, 255, 255, 0.8));
}
@keyframes rotate {
0% { transform: translate(-50%, -50%) rotate(0deg); }
100% { transform: translate(-50%, -50%) rotate(360deg); }
}
.center-line {
position: absolute;
left: 50%;
top: 0;
bottom: 0;
width: 2px;
background: rgba(255, 255, 255, 0.2);
transform: translateX(-50%);
}
.center-line::before {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 10px;
height: 10px;
background: rgba(255, 255, 255, 0.2);
border-radius: 50%;
transform: translate(-50%, -50%);
}
.controls {
text-align: center;
color: rgba(255, 255, 255, 0.7);
margin-top: 10px;
font-size: 14px;
}
.game-over {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 10;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s;
}
.game-over.active {
opacity: 1;
pointer-events: all;
}
.game-over h2 {
color: white;
font-size: 48px;
margin-bottom: 20px;
text-shadow: 0 0 20px rgba(135, 206, 250, 0.8);
}
.game-over p {
color: #4facfe;
font-size: 24px;
margin-bottom: 30px;
}
.restart-btn {
background: linear-gradient(45deg, #4facfe, #00f2fe);
color: white;
border: none;
padding: 15px 30px;
font-size: 18px;
border-radius: 25px;
cursor: pointer;
box-shadow: 0 5px 15px rgba(79, 172, 254, 0.4);
transition: all 0.3s;
}
.restart-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(79, 172, 254, 0.6);
}
.sound-toggle {
position: absolute;
top: 10px;
right: 10px;
background: transparent;
border: none;
color: rgba(255, 255, 255, 0.7);
font-size: 20px;
cursor: pointer;
z-index: 5;
}
.snow-effect {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 1;
}
.snow {
position: absolute;
background: white;
border-radius: 50%;
opacity: 0.8;
pointer-events: none;
}
.start-screen {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.9);
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
z-index: 20;
color: white;
text-align: center;
padding: 20px;
}
.start-screen h2 {
font-size: 36px;
margin-bottom: 20px;
text-shadow: 0 0 10px rgba(135, 206, 250, 0.8);
}
.start-option {
margin: 15px 0;
font-size: 18px;
color: rgba(255, 255, 255, 0.9);
}
.mode-btn, .difficulty-btn {
display: inline-block;
padding: 8px 16px;
margin: 0 10px;
border: 2px solid rgba(255, 255, 255, 0.3);
background: transparent;
color: white;
border-radius: 20px;
cursor: pointer;
font-size: 14px;
transition: all 0.3s;
}
.mode-btn.active, .difficulty-btn.active {
background: rgba(79, 172, 254, 0.4);
border-color: #4facfe;
box-shadow: 0 0 10px rgba(79, 172, 254, 0.5);
}
.mode-btn:hover, .difficulty-btn:hover {
background: rgba(255, 255, 255, 0.1);
}
.start-btn {
margin-top: 30px;
padding: 15px 40px;
background: linear-gradient(45deg, #4facfe, #00f2fe);
color: white;
border: none;
border-radius: 30px;
font-size: 18px;
cursor: pointer;
box-shadow: 0 5px 15px rgba(79, 172, 254, 0.4);
transition: all 0.3s;
}
.start-btn:hover {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(79, 172, 254, 0.6);
}
.focus-hint {
margin-top: 20px;
padding: 10px 20px;
background: rgba(255, 255, 255, 0.1);
border-radius: 10px;
color: #4facfe;
font-size: 16px;
cursor: pointer;
border: 1px solid rgba(255, 255, 255, 0.3);
}
.debug-info {
position: absolute;
top: 10px;
left: 10px;
color: #00ff00;
font-size: 12px;
z-index: 10;
background: rgba(0, 0, 0, 0.7);
padding: 5px;
border-radius: 5px;
}
</style>
</head>
<body>
<div class="game-container">
<div class="game-title">❄️ Snow Pong ❄️</div>
<button class="sound-toggle" id="sound-btn">?</button>
<div class="score-board">
<div class="score" id="left-score">0</div>
<div class="score" id="right-score">0</div>
</div>
<div class="session-score">
Всего голов за сессию: <span id="total-goals">0</span>
</div>
<div class="center-line"></div>
<div class="paddle left-paddle" id="left-paddle"></div>
<div class="paddle right-paddle" id="right-paddle"></div>
<div class="snowflake" id="snowflake"></div>
<div class="snow-effect" id="snow-effect"></div>
<div class="game-over" id="game-over">
<h2>Игра окончена!</h2>
<p id="winner-text">Победитель: Игрок 1</p>
<button class="restart-btn" id="restart-btn">Новая игра</button>
</div>
<div class="controls">
<div id="control-hint">Управление: W/S</div>
</div>
<div class="start-screen" id="start-screen">
<h2>Добро пожаловать в Snow Pong! ❄️</h2>
<div class="start-option">
<strong>Режим игры:</strong><br>
<button class="mode-btn active" data-mode="pvp">PVP</button>
<button class="mode-btn" data-mode="pve">PVE</button>
</div>
<div class="start-option" id="difficulty-section">
<strong>Сложность (для PVE):</strong><br>
<button class="difficulty-btn active" data-level="easy">Лёгкий</button>
<button class="difficulty-btn" data-level="medium">Средний</button>
<button class="difficulty-btn" data-level="hard">Сложный</button>
</div>
<button class="start-btn" id="start-game-btn">Начать игру</button>
<div class="focus-hint" id="focus-btn">? Кликните сюда для фокуса</div>
</div>
<div class="debug-info" id="debug">Последняя клавиша: —</div>
</div>
<script>
// Элементы
const gameContainer = document.querySelector('.game-container');
const leftPaddle = document.getElementById('left-paddle');
const rightPaddle = document.getElementById('right-paddle');
const snowflake = document.getElementById('snowflake');
const leftScoreElement = document.getElementById('left-score');
const rightScoreElement = document.getElementById('right-score');
const totalGoalsElement = document.getElementById('total-goals');
const gameOverScreen = document.getElementById('game-over');
const winnerText = document.getElementById('winner-text');
const restartBtn = document.getElementById('restart-btn');
const snowEffect = document.getElementById('snow-effect');
const soundBtn = document.getElementById('sound-btn');
const controlHint = document.getElementById('control-hint');
const startScreen = document.getElementById('start-screen');
const debug = document.getElementById('debug');
// Настройки
let gameMode = 'pvp';
let difficulty = 'medium';
let soundEnabled = true;
let audioContext = null;
// Параметры
const gameWidth = 800;
const gameHeight = 600;
const paddleHeight = 100;
const paddleWidth = 15;
const snowflakeSize = 30;
const paddleSpeed = 8;
const maxScore = 5;
// Игровые переменные
let leftPaddleY = gameHeight / 2 - paddleHeight / 2;
let rightPaddleY = gameHeight / 2 - paddleHeight / 2;
let snowflakeX = gameWidth / 2;
let snowflakeY = gameHeight / 2;
let snowflakeVelX = 5;
let snowflakeVelY = 3;
let leftScore = 0;
let rightScore = 0;
let totalGoals = 0;
let gameActive = false;
// Управление
const keys = { w: false, s: false, o: false, l: false };
// --- НАСТРОЙКИ СЛОЖНОСТИ ---
const difficultySettings = {
easy: { speed: 0.1, error: 30, multiplier: 1 },
medium: { speed: 0.15, error: 10, multiplier: 2 },
hard: { speed: 0.2, error: 2, multiplier: 3 }
};
// --- УПРОЩЁННЫЙ ИИ (без застревания) ---
function moveAiPaddle() {
if (gameMode !== 'pve') return;
const settings = difficultySettings[difficulty];
const rightPaddleCenter = rightPaddleY + paddleHeight / 2;
let targetY = snowflakeY;
const error = difficulty === 'hard' ? 0 : (Math.random() * settings.error - settings.error / 2);
const finalTarget = targetY + error;
const diff = finalTarget - rightPaddleCenter;
const threshold = difficulty === 'hard' ? 2 : 5;
if (Math.abs(diff) > threshold) {
const moveSpeed = paddleSpeed * settings.speed * settings.multiplier;
if (diff > 0) {
rightPaddleY += moveSpeed;
} else {
rightPaddleY -= moveSpeed;
}
}
if (rightPaddleY < 0) rightPaddleY = 0;
if (rightPaddleY > gameHeight - paddleHeight) rightPaddleY = gameHeight - paddleHeight;
}
// --- АУДИО ---
function initAudio() {
if (audioContext) return;
try {
audioContext = new (window.AudioContext || window.webkitAudioContext)();
} catch (e) {
console.warn('Audio not available');
}
}
function playSound(freq, dur = 0.1) {
if (!soundEnabled || !audioContext) return;
const osc = audioContext.createOscillator();
const gain = audioContext.createGain();
osc.connect(gain);
gain.connect(audioContext.destination);
osc.frequency.value = freq;
osc.type = 'square';
gain.gain.setValueAtTime(0.1, audioContext.currentTime);
gain.gain.exponentialRampToValueAtTime(0.001, audioContext.currentTime + dur);
osc.start();
osc.stop(audioContext.currentTime + dur);
}
function playBounce() { playSound(300); }
function playScore() { playSound(150, 0.2); }
function playWin() { playSound(800, 0.3); }
soundBtn.addEventListener('click', () => {
soundEnabled = !soundEnabled;
soundBtn.textContent = soundEnabled ? '?' : '?';
});
// --- СНЕГ ---
function createSnowflakes() {
for (let i = 0; i < 20; i++) {
const snow = document.createElement('div');
snow.classList.add('snow');
const size = Math.random() * 6 + 2;
snow.style.width = `${size}px`;
snow.style.height = `${size}px`;
snow.style.left = `${Math.random() * 100}%`;
snow.style.top = `${Math.random() * 100}%`;
snow.style.opacity = Math.random() * 0.7 + 0.3;
snow.dataset.speed = Math.random() * 2 + 1;
snowEffect.appendChild(snow);
}
}
function animateSnowflakes() {
document.querySelectorAll('.snow').forEach(snow => {
let top = parseFloat(snow.style.top) + parseFloat(snow.dataset.speed);
if (top > 100) top = -5;
snow.style.top = `${top}%`;
});
}
// --- ВЫБОР НА СТАРТЕ ---
const modeButtons = document.querySelectorAll('.mode-btn');
const difficultyButtons = document.querySelectorAll('.difficulty-btn');
const difficultySection = document.getElementById('difficulty-section');
const startGameBtn = document.getElementById('start-game-btn');
const focusBtn = document.getElementById('focus-btn');
modeButtons.forEach(btn => {
btn.addEventListener('click', () => {
modeButtons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
gameMode = btn.dataset.mode;
difficultySection.style.display = gameMode === 'pve' ? 'block' : 'none';
updateControlHint();
});
});
difficultyButtons.forEach(btn => {
btn.addEventListener('click', () => {
difficultyButtons.forEach(b => b.classList.remove('active'));
btn.classList.add('active');
difficulty = btn.dataset.level;
});
});
// --- ФОКУС ---
function setFocus() {
document.body.focus();
debug.textContent = 'Фокус установлен';
setTimeout(() => debug.textContent = 'Последняя клавиша: —', 1000);
}
focusBtn.addEventListener('click', setFocus);
startGameBtn.addEventListener('click', setFocus);
// --- УПРАВЛЕНИЕ ---
document.addEventListener('keydown', (e) => {
const key = e.key.toLowerCase();
debug.textContent = `Key down: ${e.key}`;
if (keys.hasOwnProperty(key)) {
keys[key] = true;
e.preventDefault();
}
});
document.addEventListener('keyup', (e) => {
const key = e.key.toLowerCase();
if (keys.hasOwnProperty(key)) {
keys[key] = false;
}
});
// --- ИГРОВАЯ ЛОГИКА ---
function updateControlHint() {
controlHint.textContent = gameMode === 'pvp'
? 'Игрок 1: W/S | Игрок 2: O/L'
: 'Вы играете за левую ракетку. Управление: W/S';
}
function checkCollision(el1, el2) {
const r1 = el1.getBoundingClientRect();
const r2 = el2.getBoundingClientRect();
return !(r1.right < r2.left || r1.left > r2.right || r1.bottom < r2.top || r1.top > r2.bottom);
}
function resetSnowflake() {
snowflakeX = gameWidth / 2;
snowflakeY = gameHeight / 2;
snowflakeVelX = 5 * (Math.random() > 0.5 ? 1 : -1);
snowflakeVelY = 3 * (Math.random() > 0.5 ? 1 : -1);
updateSnowflakePosition();
}
function updateSnowflakePosition() {
snowflake.style.left = `${snowflakeX}px`;
snowflake.style.top = `${snowflakeY}px`;
}
function updatePaddlePositions() {
leftPaddle.style.top = `${leftPaddleY}px`;
rightPaddle.style.top = `${rightPaddleY}px`;
}
function resetGame() {
leftScore = 0;
rightScore = 0;
leftScoreElement.textContent = '0';
rightScoreElement.textContent = '0';
leftPaddleY = gameHeight / 2 - paddleHeight / 2;
rightPaddleY = gameHeight / 2 - paddleHeight / 2;
resetSnowflake();
updatePaddlePositions();
}
// --- ИГРОВОЙ ЦИКЛ ---
function gameLoop() {
if (gameActive) {
// Управление
if (gameMode === 'pvp') {
if (keys.w) leftPaddleY = Math.max(0, leftPaddleY - paddleSpeed);
if (keys.s) leftPaddleY = Math.min(gameHeight - paddleHeight, leftPaddleY + paddleSpeed);
if (keys.o) rightPaddleY = Math.max(0, rightPaddleY - paddleSpeed);
if (keys.l) rightPaddleY = Math.min(gameHeight - paddleHeight, rightPaddleY + paddleSpeed);
} else if (gameMode === 'pve') {
if (keys.w) leftPaddleY = Math.max(0, leftPaddleY - paddleSpeed);
if (keys.s) leftPaddleY = Math.min(gameHeight - paddleHeight, leftPaddleY + paddleSpeed);
moveAiPaddle();
}
// Движение снежинки
snowflakeX += snowflakeVelX;
snowflakeY += snowflakeVelY;
updateSnowflakePosition();
// Отскок от стен
if (snowflakeY <= 0 || snowflakeY >= gameHeight - 6) {
snowflakeVelY = -snowflakeVelY;
playBounce();
}
// Столкновение
if (checkCollision(snowflake, leftPaddle) || checkCollision(snowflake, rightPaddle)) {
snowflakeVelX = -snowflakeVelX * 1.05;
if (checkCollision(snowflake, rightPaddle)) {
snowflakeVelX *= 1.03;
}
playBounce();
}
// Гол
if (snowflakeX < 0) {
rightScore++;
totalGoals++;
playScore();
resetSnowflake();
} else if (snowflakeX > gameWidth) {
leftScore++;
totalGoals++;
playScore();
resetSnowflake();
}
// Победа
if (leftScore >= maxScore || rightScore >= maxScore) {
gameActive = false;
playWin();
gameOverScreen.classList.add('active');
winnerText.textContent = leftScore >= maxScore
? (gameMode === 'pve' ? '? Вы победили!' : 'Победитель: Игрок 1!')
: (gameMode === 'pve' ? '? Компьютер победил!' : 'Победитель: Игрок 2!');
}
// Обновление
leftScoreElement.textContent = leftScore;
rightScoreElement.textContent = rightScore;
totalGoalsElement.textContent = totalGoals;
updatePaddlePositions();
animateSnowflakes();
}
requestAnimationFrame(gameLoop);
}
// --- ЗАПУСК ИГРЫ ---
startGameBtn.addEventListener('click', () => {
startScreen.style.display = 'none';
initAudio();
setFocus();
gameActive = true;
updateControlHint();
requestAnimationFrame(gameLoop);
});
restartBtn.addEventListener('click', () => {
resetGame();
gameOverScreen.classList.remove('active');
gameActive = true;
setFocus();
});
// --- ИНИЦИАЛИЗАЦИЯ ---
window.onload = () => {
createSnowflakes();
difficultySection.style.display = 'none';
updateControlHint();
document.body.tabIndex = 0;
document.body.focus();
};
</script>
</body>
</html>
Комментарии (7)
Mr_Zavod
04.08.2025 14:17Хотите сказать, что в будущем люди будут играть только в понг?
Ужасное будущее
monowar
Знатная простыня!