artifacts/snake.html (194 lines of code) (raw):
<!DOCTYPE html>
<!--
Copyright 2024 -l
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Snake Game</title>
<style>
body {
margin: 0;
display: flex;
justify-content: center;
align-items: center;
min-height: 100vh;
font-family: sans-serif;
background-color: #f0f0f0;
}
#gameContainer {
background-color: #fff;
border: 1px solid #ddd;
padding: 20px;
border-radius: 5px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
canvas {
background-color: #eee;
border: 1px solid #ddd;
}
#controls {
margin-top: 20px;
display: flex;
justify-content: center;
}
button {
padding: 10px 20px;
margin: 0 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
#score {
margin-top: 10px;
text-align: center;
font-size: 1.2em;
}
</style>
</head>
<body>
<div id="gameContainer">
<h1>Snake Game</h1>
<canvas id="gameCanvas" width="400" height="400"></canvas>
<div id="controls">
<button id="startButton">Start</button>
<button id="pauseButton" disabled>Pause</button>
</div>
<div id="score">Score: 0</div>
</div>
<script>
const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const gridSize = 20;
let snake = [{ x: 10, y: 10 }];
let food = {};
let direction = 'right';
let score = 0;
let gameRunning = false;
let intervalId;
// Generate random food position
function generateFood() {
food = {
x: Math.floor(Math.random() * (canvas.width / gridSize)),
y: Math.floor(Math.random() * (canvas.height / gridSize))
};
}
// Draw the snake
function drawSnake() {
ctx.fillStyle = 'green';
snake.forEach((segment, index) => {
ctx.fillRect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
if (index === 0) {
ctx.fillStyle = 'darkgreen';
ctx.fillRect(segment.x * gridSize + 2, segment.y * gridSize + 2, gridSize - 4, gridSize - 4);
}
});
}
// Draw the food
function drawFood() {
ctx.fillStyle = 'red';
ctx.fillRect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
}
// Update the snake's position
function updateSnake() {
const head = { x: snake[0].x, y: snake[0].y };
switch (direction) {
case 'up':
head.y--;
break;
case 'down':
head.y++;
break;
case 'left':
head.x--;
break;
case 'right':
head.x++;
break;
}
// Check for collisions
if (head.x < 0 || head.x >= canvas.width / gridSize || head.y < 0 || head.y >= canvas.height / gridSize || checkCollision(head)) {
gameOver();
return;
}
// Add the new head to the snake
snake.unshift(head);
// Check if the snake ate the food
if (head.x === food.x && head.y === food.y) {
score++;
document.getElementById('score').textContent = `Score: ${score}`;
generateFood();
} else {
// Remove the tail if the snake didn't eat the food
snake.pop();
}
}
// Check if the snake collided with itself
function checkCollision(head) {
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
return true;
}
}
return false;
}
// Game over function
function gameOver() {
clearInterval(intervalId);
gameRunning = false;
document.getElementById('startButton').disabled = false;
document.getElementById('pauseButton').disabled = true;
alert('Game Over! Your score is: ' + score);
}
// Start the game
function startGame() {
if (!gameRunning) {
gameRunning = true;
document.getElementById('startButton').disabled = true;
document.getElementById('pauseButton').disabled = false;
generateFood();
intervalId = setInterval(gameLoop, 100);
}
}
// Pause the game
function pauseGame() {
if (gameRunning) {
clearInterval(intervalId);
gameRunning = false;
document.getElementById('pauseButton').disabled = true;
document.getElementById('startButton').disabled = false;
}
}
// Game loop
function gameLoop() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSnake();
drawFood();
updateSnake();
}
// Event listeners for keyboard input
document.addEventListener('keydown', (e) => {
switch (e.key) {
case 'ArrowUp':
if (direction !== 'down') direction = 'up';
break;
case 'ArrowDown':
if (direction !== 'up') direction = 'down';
break;
case 'ArrowLeft':
if (direction !== 'right') direction = 'left';
break;
case 'ArrowRight':
if (direction !== 'left') direction = 'right';
break;
}
});
// Event listeners for buttons
document.getElementById('startButton').addEventListener('click', startGame);
document.getElementById('pauseButton').addEventListener('click', pauseGame);
</script>
</body>
</html>