Files
Snake/script.js
2025-12-10 13:56:56 +01:00

176 lines
4.8 KiB
JavaScript

// HTML elements
const board = document.getElementById('game-board');
const instructionText = document.getElementById('instruction-text');
const logo = document.getElementById('logo');
const score = document.getElementById('score');
const highScoreText = document.getElementById('highScore');
// Game variables
const gridSize = 20;
let snake = [{ x: 10, y: 10 }];
let food = generateFood();
let highScore = 0;
let direction = 'right';
let gameInterval;
let gameSpeedDelay = 200;
let gameStarted = false;
// Swipe variables
let touchStartX = 0;
let touchStartY = 0;
let touchEndX = 0;
let touchEndY = 0;
const minSwipeDistance = 30;
// Draw game
function draw() {
board.innerHTML = '';
drawSnake();
drawFood();
updateScore();
}
// Draw snake
function drawSnake() {
snake.forEach(segment => {
const snakeElement = document.createElement('div');
snakeElement.className = 'snake';
snakeElement.style.gridColumnStart = segment.x;
snakeElement.style.gridRowStart = segment.y;
board.appendChild(snakeElement);
});
}
// Draw food
function drawFood() {
if (!gameStarted) return;
const foodElement = document.createElement('div');
foodElement.className = 'food';
foodElement.style.gridColumnStart = food.x;
foodElement.style.gridRowStart = food.y;
board.appendChild(foodElement);
}
// Generate food
function generateFood() {
return {
x: Math.floor(Math.random() * gridSize) + 1,
y: Math.floor(Math.random() * gridSize) + 1
};
}
// Move snake
function move() {
const head = { ...snake[0] };
switch (direction) {
case 'up': head.y--; break;
case 'down': head.y++; break;
case 'left': head.x--; break;
case 'right': head.x++; break;
}
snake.unshift(head);
if (head.x === food.x && head.y === food.y) {
food = generateFood();
increaseSpeed();
resetInterval();
} else snake.pop();
}
// Start game
function startGame() {
if (gameStarted) return;
gameStarted = true;
instructionText.style.display = 'none';
logo.style.display = 'none';
gameInterval = setInterval(() => { move(); checkCollision(); draw(); }, gameSpeedDelay);
}
// Keyboard control
function handleKeyPress(e) {
if (!gameStarted && (e.code === 'Space' || e.key === ' ')) startGame();
if (e.key === 'ArrowUp' && direction !== 'down') direction = 'up';
if (e.key === 'ArrowDown' && direction !== 'up') direction = 'down';
if (e.key === 'ArrowLeft' && direction !== 'right') direction = 'left';
if (e.key === 'ArrowRight' && direction !== 'left') direction = 'right';
}
document.addEventListener('keydown', handleKeyPress);
// Swipe control
board.addEventListener('touchstart', e => {
const touch = e.touches[0];
touchStartX = touch.clientX;
touchStartY = touch.clientY;
});
board.addEventListener('touchend', e => {
const touch = e.changedTouches[0];
touchEndX = touch.clientX;
touchEndY = touch.clientY;
handleSwipe();
});
board.addEventListener('touchmove', e => e.preventDefault(), { passive: false });
function handleSwipe() {
const dx = touchEndX - touchStartX;
const dy = touchEndY - touchStartY;
if (Math.abs(dx) < minSwipeDistance && Math.abs(dy) < minSwipeDistance) return;
if (Math.abs(dx) > Math.abs(dy)) {
if (dx > 0 && direction !== 'left') direction = 'right';
else if (dx < 0 && direction !== 'right') direction = 'left';
} else {
if (dy > 0 && direction !== 'up') direction = 'down';
else if (dy < 0 && direction !== 'down') direction = 'up';
}
if (!gameStarted) startGame();
}
// Increase speed
function increaseSpeed() {
if (gameSpeedDelay > 150) gameSpeedDelay -= 5;
else if (gameSpeedDelay > 100) gameSpeedDelay -= 3;
else if (gameSpeedDelay > 50) gameSpeedDelay -= 2;
else if (gameSpeedDelay > 25) gameSpeedDelay -= 1;
}
function resetInterval() {
clearInterval(gameInterval);
gameInterval = setInterval(() => { move(); checkCollision(); draw(); }, gameSpeedDelay);
}
// Collision
function checkCollision() {
const head = snake[0];
if (head.x < 1 || head.x > gridSize || head.y < 1 || head.y > gridSize) resetGame();
for (let i = 1; i < snake.length; i++) if (head.x === snake[i].x && head.y === snake[i].y) resetGame();
}
// Reset game
function resetGame() {
updateHighScore();
stopGame();
snake = [{ x: 10, y: 10 }];
food = generateFood();
direction = 'right';
gameSpeedDelay = 200;
draw();
}
// Score
function updateScore() {
score.textContent = (snake.length - 1).toString().padStart(3, '0');
}
function stopGame() {
clearInterval(gameInterval);
gameStarted = false;
instructionText.style.display = 'block';
logo.style.display = 'block';
}
function updateHighScore() {
const currentScore = snake.length - 1;
if (currentScore > highScore) {
highScore = currentScore;
highScoreText.textContent = highScore.toString().padStart(3, '0');
}
highScoreText.style.display = 'block';
}