Files
Snake/script.js

176 lines
4.8 KiB
JavaScript
Raw Permalink Normal View History

2025-12-10 13:56:56 +01:00
// 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');
2023-11-28 20:53:58 +01:00
2025-12-10 13:56:56 +01:00
// Game variables
const gridSize = 20;
let snake = [{ x: 10, y: 10 }];
let food = generateFood();
let highScore = 0;
let direction = 'right';
2023-11-28 20:53:58 +01:00
let gameInterval;
let gameSpeedDelay = 200;
let gameStarted = false;
2023-11-28 20:53:58 +01:00
2025-12-10 13:56:56 +01:00
// Swipe variables
let touchStartX = 0;
let touchStartY = 0;
let touchEndX = 0;
let touchEndY = 0;
const minSwipeDistance = 30;
// Draw game
2023-11-28 20:53:58 +01:00
function draw() {
board.innerHTML = '';
drawSnake();
drawFood();
2023-11-28 20:53:58 +01:00
updateScore();
}
// Draw snake
2023-11-28 20:53:58 +01:00
function drawSnake() {
2025-12-10 13:56:56 +01:00
snake.forEach(segment => {
const snakeElement = document.createElement('div');
snakeElement.className = 'snake';
snakeElement.style.gridColumnStart = segment.x;
snakeElement.style.gridRowStart = segment.y;
board.appendChild(snakeElement);
2023-11-28 20:53:58 +01:00
});
}
2025-12-10 13:56:56 +01:00
// Draw food
2023-11-28 20:53:58 +01:00
function drawFood() {
2025-12-10 13:56:56 +01:00
if (!gameStarted) return;
const foodElement = document.createElement('div');
foodElement.className = 'food';
foodElement.style.gridColumnStart = food.x;
foodElement.style.gridRowStart = food.y;
board.appendChild(foodElement);
2023-11-28 20:53:58 +01:00
}
// Generate food
2023-11-28 20:53:58 +01:00
function generateFood() {
2025-12-10 13:56:56 +01:00
return {
x: Math.floor(Math.random() * gridSize) + 1,
y: Math.floor(Math.random() * gridSize) + 1
};
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
// Move snake
2023-11-28 20:53:58 +01:00
function move() {
const head = { ...snake[0] };
switch (direction) {
2025-12-10 13:56:56 +01:00
case 'up': head.y--; break;
case 'down': head.y++; break;
case 'left': head.x--; break;
case 'right': head.x++; break;
2023-11-28 20:53:58 +01:00
}
snake.unshift(head);
2023-11-28 20:53:58 +01:00
if (head.x === food.x && head.y === food.y) {
food = generateFood();
increaseSpeed();
2025-12-10 13:56:56 +01:00
resetInterval();
} else snake.pop();
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
// Start game
2023-11-28 20:53:58 +01:00
function startGame() {
2025-12-10 13:56:56 +01:00
if (gameStarted) return;
gameStarted = true;
instructionText.style.display = 'none';
2023-11-28 20:53:58 +01:00
logo.style.display = 'none';
2025-12-10 13:56:56 +01:00
gameInterval = setInterval(() => { move(); checkCollision(); draw(); }, gameSpeedDelay);
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
// 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';
2023-11-28 20:53:58 +01:00
} else {
2025-12-10 13:56:56 +01:00
if (dy > 0 && direction !== 'up') direction = 'down';
else if (dy < 0 && direction !== 'down') direction = 'up';
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
if (!gameStarted) startGame();
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
// Increase speed
2023-11-28 20:53:58 +01:00
function increaseSpeed() {
2025-12-10 13:56:56 +01:00
if (gameSpeedDelay > 150) gameSpeedDelay -= 5;
else if (gameSpeedDelay > 100) gameSpeedDelay -= 3;
else if (gameSpeedDelay > 50) gameSpeedDelay -= 2;
else if (gameSpeedDelay > 25) gameSpeedDelay -= 1;
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
function resetInterval() {
clearInterval(gameInterval);
gameInterval = setInterval(() => { move(); checkCollision(); draw(); }, gameSpeedDelay);
}
// Collision
2023-11-28 20:53:58 +01:00
function checkCollision() {
const head = snake[0];
2025-12-10 13:56:56 +01:00
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();
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
// Reset game
2023-11-28 20:53:58 +01:00
function resetGame() {
updateHighScore();
stopGame();
2023-11-28 20:53:58 +01:00
snake = [{ x: 10, y: 10 }];
food = generateFood();
direction = 'right';
gameSpeedDelay = 200;
2025-12-10 13:56:56 +01:00
draw();
2023-11-28 20:53:58 +01:00
}
2025-12-10 13:56:56 +01:00
// Score
2023-11-28 20:53:58 +01:00
function updateScore() {
2025-12-10 13:56:56 +01:00
score.textContent = (snake.length - 1).toString().padStart(3, '0');
2023-11-28 20:53:58 +01:00
}
function stopGame() {
clearInterval(gameInterval);
gameStarted = false;
2023-11-28 20:53:58 +01:00
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';
}