diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..269c891
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,3 @@
+FROM nginx:alpine
+COPY . /usr/share/nginx/html
+EXPOSE 80
diff --git a/index.html b/index.html
index 42c4c99..87dc129 100644
--- a/index.html
+++ b/index.html
@@ -1,33 +1,24 @@
-
-
-
-
000
- 000
-
-
+
+
+
+
+
+
+
Snake Game
+
+
+
+
+
+
+
000
+ 000
-
Press spacebar to start the game
+
+
Press spacebar or tap to start the game

-
+
+
diff --git a/script.js b/script.js
index 74dbcc9..a666e53 100644
--- a/script.js
+++ b/script.js
@@ -1,11 +1,11 @@
-// Define HTML elements
+// 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');
-// Define game variables
+// Game variables
const gridSize = 20;
let snake = [{ x: 10, y: 10 }];
let food = generateFood();
@@ -15,7 +15,14 @@ let gameInterval;
let gameSpeedDelay = 200;
let gameStarted = false;
-// Draw game map, snake, food
+// Swipe variables
+let touchStartX = 0;
+let touchStartY = 0;
+let touchEndX = 0;
+let touchEndY = 0;
+const minSwipeDistance = 30;
+
+// Draw game
function draw() {
board.innerHTML = '';
drawSnake();
@@ -25,153 +32,119 @@ function draw() {
// Draw snake
function drawSnake() {
- snake.forEach((segment) => {
- const snakeElement = createGameElement('div', 'snake');
- setPosition(snakeElement, segment);
+ snake.forEach(segment => {
+ const snakeElement = document.createElement('div');
+ snakeElement.className = 'snake';
+ snakeElement.style.gridColumnStart = segment.x;
+ snakeElement.style.gridRowStart = segment.y;
board.appendChild(snakeElement);
});
}
-// Create a snake or food cube/div
-function createGameElement(tag, className) {
- const element = document.createElement(tag);
- element.className = className;
- return element;
-}
-
-// Set the position of snake or food
-function setPosition(element, position) {
- element.style.gridColumn = position.x;
- element.style.gridRow = position.y;
-}
-
-// Testing draw function
-// draw();
-
-// Draw food function
+// Draw food
function drawFood() {
- if (gameStarted) {
- const foodElement = createGameElement('div', 'food');
- setPosition(foodElement, food);
- board.appendChild(foodElement);
- }
+ 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() {
- const x = Math.floor(Math.random() * gridSize) + 1;
- const y = Math.floor(Math.random() * gridSize) + 1;
- return { x, y };
+ return {
+ x: Math.floor(Math.random() * gridSize) + 1,
+ y: Math.floor(Math.random() * gridSize) + 1
+ };
}
-// Moving the snake
+// 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;
+ case 'up': head.y--; break;
+ case 'down': head.y++; break;
+ case 'left': head.x--; break;
+ case 'right': head.x++; break;
}
-
snake.unshift(head);
- // snake.pop();
-
if (head.x === food.x && head.y === food.y) {
food = generateFood();
increaseSpeed();
- clearInterval(gameInterval); // Clear past interval
- gameInterval = setInterval(() => {
- move();
- checkCollision();
- draw();
- }, gameSpeedDelay);
- } else {
- snake.pop();
- }
+ resetInterval();
+ } else snake.pop();
}
-// Test moving
-// setInterval(() => {
-// move(); // Move first
-// draw(); // Then draw again new position
-// }, 200);
-
-// Start game function
+// Start game
function startGame() {
- gameStarted = true; // Keep track of a running game
+ if (gameStarted) return;
+ gameStarted = true;
instructionText.style.display = 'none';
logo.style.display = 'none';
- gameInterval = setInterval(() => {
- move();
- checkCollision();
- draw();
- }, gameSpeedDelay);
+ gameInterval = setInterval(() => { move(); checkCollision(); draw(); }, gameSpeedDelay);
}
-// Keypress event listener
-function handleKeyPress(event) {
- if (
- (!gameStarted && event.code === 'Space') ||
- (!gameStarted && event.key === ' ')
- ) {
- startGame();
- } else {
- switch (event.key) {
- case 'ArrowUp':
- direction = 'up';
- break;
- case 'ArrowDown':
- direction = 'down';
- break;
- case 'ArrowLeft':
- direction = 'left';
- break;
- case 'ArrowRight':
- direction = 'right';
- break;
- }
- }
+// 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);
-function increaseSpeed() {
- // console.log(gameSpeedDelay);
- if (gameSpeedDelay > 150) {
- gameSpeedDelay -= 5;
- } else if (gameSpeedDelay > 100) {
- gameSpeedDelay -= 3;
- } else if (gameSpeedDelay > 50) {
- gameSpeedDelay -= 2;
- } else if (gameSpeedDelay > 25) {
- gameSpeedDelay -= 1;
+// 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();
- }
- }
+ 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();
@@ -179,21 +152,19 @@ function resetGame() {
food = generateFood();
direction = 'right';
gameSpeedDelay = 200;
- updateScore();
+ draw();
}
+// Score
function updateScore() {
- const currentScore = snake.length - 1;
- score.textContent = currentScore.toString().padStart(3, '0');
+ 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) {
diff --git a/style.css b/style.css
index eba3e6b..2d5c647 100644
--- a/style.css
+++ b/style.css
@@ -5,53 +5,31 @@ body {
height: 100vh;
margin: 0;
font-family: 'VT323', monospace;
-}
-
-body,
-.snake {
background-color: #414141;
}
-#game-board {
- border-radius: 100px;
- display: grid;
- grid-template-columns: repeat(20, 20px);
- grid-template-rows: repeat(20, 20px);
- margin: 5px;
-}
-
-.game-border-1 {
- border: #595f43 solid 10px;
- border-radius: 30px;
- box-shadow: inset 0 0 0 10px #595f43;
-}
-
-.game-border-2 {
- border: #abb78a solid 8px;
- border-radius: 26px;
- box-shadow: inset 0 0 0 10px #abb78a;
-}
-
-.game-border-3 {
- border: #8b966c solid 30px;
- border-radius: 20px;
- box-shadow: inset 0 0 0 5px #8b966c;
-}
-
-#instruction-text {
- position: absolute;
- top: 60%;
- color: #333;
- width: 300px;
+.container {
+ position: relative;
text-align: center;
- text-transform: capitalize;
- padding: 30px;
- margin: 0;
+}
+
+#game-board {
+ width: 400px;
+ height: 400px;
+ display: grid;
+ grid-template-columns: repeat(20, 1fr);
+ grid-template-rows: repeat(20, 1fr);
+ background-color: #c4cfa3;
+ margin: 20px auto;
+ border-radius: 20px;
+ touch-action: none; /* verhindert Scrollen bei Swipe */
}
.scores {
display: flex;
justify-content: space-between;
+ width: 400px;
+ margin: auto;
}
#score {
@@ -70,20 +48,21 @@ body,
display: none;
}
-.game-border-3,
-#logo {
- background-color: #c4cfa3;
+#instruction-text {
+ color: #333;
+ margin-top: 10px;
}
.snake {
+ background-color: #414141;
border: #5a5a5a 1px dotted;
}
.food {
background-color: #dedede;
- border: #999 5px solid;
+ border: #999 2px solid;
}
#logo {
- position: absolute;
+ margin-top: 10px;
}