HTML для игр
HTML Игры
Создание интерактивных игр с использованием HTML, Canvas и JavaScript.
1. Игра "Змейка" на Canvas
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Змейка - HTML5 Игра</title>
<style>
body {
margin: 0;
padding: 20px;
background: linear-gradient(135deg, #1e3c72, #2a5298);
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
color: white;
}
.game-container {
text-align: center;
background: rgba(255, 255, 255, 0.1);
backdrop-filter: blur(10px);
border-radius: 20px;
padding: 30px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
border: 1px solid rgba(255, 255, 255, 0.2);
}
h1 {
margin-bottom: 10px;
font-size: 2.5em;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.5);
}
.score-container {
display: flex;
justify-content: space-around;
margin: 20px 0;
font-size: 1.2em;
}
.score-item {
background: rgba(255, 255, 255, 0.2);
padding: 10px 20px;
border-radius: 10px;
min-width: 120px;
}
canvas {
border: 3px solid rgba(255, 255, 255, 0.3);
border-radius: 10px;
background: rgba(0, 0, 0, 0.3);
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.2);
}
.controls {
margin: 20px 0;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
max-width: 300px;
margin-left: auto;
margin-right: auto;
}
button {
background: rgba(255, 255, 255, 0.2);
border: 2px solid rgba(255, 255, 255, 0.3);
color: white;
padding: 15px;
border-radius: 10px;
cursor: pointer;
font-size: 16px;
font-weight: bold;
transition: all 0.3s ease;
}
button:hover {
background: rgba(255, 255, 255, 0.3);
transform: translateY(-2px);
}
.game-over {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.9);
padding: 40px;
border-radius: 15px;
text-align: center;
z-index: 10;
}
.instructions {
margin-top: 20px;
background: rgba(255, 255, 255, 0.1);
padding: 15px;
border-radius: 10px;
font-size: 0.9em;
}
.mobile-controls {
display: none;
grid-template-columns: repeat(3, 1fr);
grid-template-rows: repeat(3, 1fr);
gap: 10px;
margin-top: 20px;
max-width: 200px;
margin-left: auto;
margin-right: auto;
}
@media (max-width: 768px) {
.mobile-controls {
display: grid;
}
.controls {
display: none;
}
}
</style>
</head>
<body>
<div class="game-container">
<h1>? Змейка</h1>
<div class="score-container">
<div class="score-item">
<div>ОЧКИ</div>
<div id="score">0</div>
</div>
<div class="score-item">
<div>РЕКОРД</div>
<div id="highScore">0</div>
</div>
</div>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div class="controls">
<div></div>
<button onclick="changeDirection("UP")">⬆️ ВВЕРХ</button>
<div></div>
<button onclick="changeDirection("LEFT")">⬅️ ЛЕВО</button>
<button onclick="togglePause()" id="pauseBtn">⏸️ ПАУЗА</button>
<button onclick="changeDirection("RIGHT")">➡️ ПРАВО</button>
<div></div>
<button onclick="changeDirection("DOWN")">⬇️ ВНИЗ</button>
<div></div>
</div>
<div class="mobile-controls">
<div></div>
<button onclick="changeDirection("UP")">⬆️</button>
<div></div>
<button onclick="changeDirection("LEFT")">⬅️</button>
<button onclick="togglePause()" id="mobilePauseBtn">⏸️</button>
<button onclick="changeDirection("RIGHT")">➡️</button>
<div></div>
<button onclick="changeDirection("DOWN")">⬇️</button>
<div></div>
</div>
<div class="instructions">
<p>? Управление: Стрелки клавиатуры или кнопки на экране</p>
<p>? Собирайте еду, чтобы расти и набирать очки</p>
<p>? Избегайте стен и собственного хвоста</p>
</div>
</div>
<div class="game-over" id="gameOver">
<h2 style="color: #ff6b6b;">ИГРА ОКОНЧЕНА!</h2>
<p>Ваш счет: <span id="finalScore">0</span></p>
<p>Рекорд: <span id="finalHighScore">0</span></p>
<button onclick="resetGame()" style="background: #4ecdc4; margin: 10px;">
? ИГРАТЬ СНОВА
</button>
</div>
<script>
const canvas = document.getElementById("gameCanvas");
const ctx = canvas.getContext("2d");
const scoreElement = document.getElementById("score");
const highScoreElement = document.getElementById("highScore");
const gameOverScreen = document.getElementById("gameOver");
const finalScoreElement = document.getElementById("finalScore");
const finalHighScoreElement = document.getElementById("finalHighScore");
// Константы игры
const GRID_SIZE = 20;
const TILE_COUNT = canvas.width / GRID_SIZE;
// Переменные игры
let snake = [{x: 10, y: 10}];
let food = {};
let dx = 0;
let dy = 0;
let score = 0;
let highScore = localStorage.getItem("snakeHighScore") || 0;
let gameRunning = false;
let gamePaused = false;
let gameLoop;
// Инициализация игры
function initGame() {
snake = [{x: 10, y: 10}];
generateFood();
dx = 0;
dy = 0;
score = 0;
updateScore();
highScoreElement.textContent = highScore;
gameRunning = true;
gamePaused = false;
gameOverScreen.style.display = "none";
}
// Генерация еды
function generateFood() {
food = {
x: Math.floor(Math.random() * TILE_COUNT),
y: Math.floor(Math.random() * TILE_COUNT)
};
// Проверка, чтобы еда не появилась на змейке
for (let segment of snake) {
if (segment.x === food.x && segment.y === food.y) {
return generateFood();
}
}
}
// Основной игровой цикл
function gameUpdate() {
if (gamePaused || !gameRunning) return;
moveSnake();
if (checkCollision()) {
gameOver();
return;
}
if (checkFoodCollision()) {
score += 10;
updateScore();
generateFood();
}
drawGame();
}
// Движение змейки
function moveSnake() {
const head = {x: snake[0].x + dx, y: snake[0].y + dy};
snake.unshift(head);
if (!checkFoodCollision()) {
snake.pop();
}
}
// Проверка столкновений
function checkCollision() {
const head = snake[0];
// Столкновение со стенами
if (head.x < 0 || head.x >= TILE_COUNT || head.y < 0 || head.y >= TILE_COUNT) {
return true;
}
// Столкновение с собой
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
return true;
}
}
return false;
}
// Проверка столкновения с едой
function checkFoodCollision() {
const head = snake[0];
return head.x === food.x && head.y === food.y;
}
// Отрисовка игры
function drawGame() {
// Очистка canvas
ctx.fillStyle = "rgba(0, 0, 0, 0.1)";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Отрисовка сетки
ctx.strokeStyle = "rgba(255, 255, 255, 0.05)";
for (let i = 0; i < TILE_COUNT; i++) {
for (let j = 0; j < TILE_COUNT; j++) {
ctx.strokeRect(i * GRID_SIZE, j * GRID_SIZE, GRID_SIZE, GRID_SIZE);
}
}
// Отрисовка змейки
snake.forEach((segment, index) => {
if (index === 0) {
// Голова змейки
ctx.fillStyle = "#4ecdc4";
ctx.fillRect(segment.x * GRID_SIZE, segment.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
// Глаза
ctx.fillStyle = "#2c3e50";
const eyeSize = GRID_SIZE / 5;
const offset = GRID_SIZE / 4;
// Левый глаз
ctx.fillRect(
segment.x * GRID_SIZE + offset,
segment.y * GRID_SIZE + offset,
eyeSize, eyeSize
);
// Правый глаз
ctx.fillRect(
segment.x * GRID_SIZE + GRID_SIZE - offset - eyeSize,
segment.y * GRID_SIZE + offset,
eyeSize, eyeSize
);
} else {
// Тело змейки
const gradient = ctx.createLinearGradient(
segment.x * GRID_SIZE, segment.y * GRID_SIZE,
(segment.x + 1) * GRID_SIZE, (segment.y + 1) * GRID_SIZE
);
gradient.addColorStop(0, "#45b7d1");
gradient.addColorStop(1, "#96ceb4");
ctx.fillStyle = gradient;
ctx.fillRect(segment.x * GRID_SIZE, segment.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
// Внутренний контур
ctx.strokeStyle = "#2c3e50";
ctx.lineWidth = 1;
ctx.strokeRect(segment.x * GRID_SIZE, segment.y * GRID_SIZE, GRID_SIZE, GRID_SIZE);
}
});
// Отрисовка еды
const foodGradient = ctx.createRadialGradient(
food.x * GRID_SIZE + GRID_SIZE/2, food.y * GRID_SIZE + GRID_SIZE/2, 0,
food.x * GRID_SIZE + GRID_SIZE/2, food.y * GRID_SIZE + GRID_SIZE/2, GRID_SIZE/2
);
foodGradient.addColorStop(0, "#ff6b6b");
foodGradient.addColorStop(1, "#ff8e8e");
ctx.fillStyle = foodGradient;
ctx.beginPath();
ctx.arc(
food.x * GRID_SIZE + GRID_SIZE/2,
food.y * GRID_SIZE + GRID_SIZE/2,
GRID_SIZE/2 - 1,
0,
Math.PI * 2
);
ctx.fill();
// Блик на еде
ctx.fillStyle = "rgba(255, 255, 255, 0.3)";
ctx.beginPath();
ctx.arc(
food.x * GRID_SIZE + GRID_SIZE/3,
food.y * GRID_SIZE + GRID_SIZE/3,
GRID_SIZE/6,
0,
Math.PI * 2
);
ctx.fill();
}
// Обновление счета
function updateScore() {
scoreElement.textContent = score;
if (score > highScore) {
highScore = score;
highScoreElement.textContent = highScore;
localStorage.setItem("snakeHighScore", highScore);
}
}
// Конец игры
function gameOver() {
gameRunning = false;
finalScoreElement.textContent = score;
finalHighScoreElement.textContent = highScore;
gameOverScreen.style.display = "block";
}
// Смена направления
function changeDirection(direction) {
if (gamePaused) return;
const goingUp = dy === -1;
const goingDown = dy === 1;
const goingRight = dx === 1;
const goingLeft = dx === -1;
switch (direction) {
case "UP":
if (!goingDown) {
dx = 0;
dy = -1;
}
break;
case "DOWN":
if (!goingUp) {
dx = 0;
dy = 1;
}
break;
case "LEFT":
if (!goingRight) {
dx = -1;
dy = 0;
}
break;
case "RIGHT":
if (!goingLeft) {
dx = 1;
dy = 0;
}
break;
}
if (!gameRunning && (dx !== 0 || dy !== 0)) {
startGame();
}
}
// Пауза/продолжение
function togglePause() {
if (!gameRunning) return;
gamePaused = !gamePaused;
const pauseBtn = document.getElementById("pauseBtn");
const mobilePauseBtn = document.getElementById("mobilePauseBtn");
if (gamePaused) {
pauseBtn.textContent = "▶️ ПРОДОЛЖИТЬ";
mobilePauseBtn.textContent = "▶️";
} else {
pauseBtn.textContent = "⏸️ ПАУЗА";
mobilePauseBtn.textContent = "⏸️";
}
}
// Сброс игры
function resetGame() {
initGame();
startGame();
}
// Запуск игры
function startGame() {
if (gameLoop) {
clearInterval(gameLoop);
}
gameRunning = true;
gameLoop = setInterval(gameUpdate, 150);
}
// Обработка клавиатуры
document.addEventListener("keydown", (e) => {
switch (e.key) {
case "ArrowUp":
e.preventDefault();
changeDirection("UP");
break;
case "ArrowDown":
e.preventDefault();
changeDirection("DOWN");
break;
case "ArrowLeft":
e.preventDefault();
changeDirection("LEFT");
break;
case "ArrowRight":
e.preventDefault();
changeDirection("RIGHT");
break;
case :
e.preventDefault();
togglePause();
break;
case "Enter":
if (!gameRunning) {
resetGame();
}
break;
}
});
// Инициализация при загрузке
window.addEventListener("load", () => {
initGame();
drawGame();
highScoreElement.textContent = highScore;
});
</script>
</body>
</html>