Update with correct files from video tutorial

This commit is contained in:
Ademir
2023-12-06 07:26:32 +01:00
parent 7f455216d7
commit 9fab4a6a9d
4 changed files with 57 additions and 285 deletions

View File

@@ -6,16 +6,12 @@
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link <link
href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=VT323&display=swap" href="https://fonts.googleapis.com/css2?family=VT323&display=swap"
rel="stylesheet" rel="stylesheet"
/> />
<link <title>Snake Game</title>
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200"
/>
<link rel="stylesheet" href="style.css" /> <link rel="stylesheet" href="style.css" />
<script src="script.js" defer></script> <script src="script.js" defer></script>
<title>Snake Game</title>
</head> </head>
<body> <body>
<div> <div>
@@ -32,6 +28,6 @@
</div> </div>
</div> </div>
<h1 id="instruction-text">Press spacebar to start the game</h1> <h1 id="instruction-text">Press spacebar to start the game</h1>
<img id="logo" src="snake-game-ai-gen.png" alt="snake logo" /> <img id="logo" src="snake-game-ai-gen.png" alt="snake-logo" />
</body> </body>
</html> </html>

View File

@@ -1,203 +0,0 @@
document.addEventListener('DOMContentLoaded', () => {
const board = document.getElementById('game-board');
const score = document.getElementById('score');
const instructionText = document.getElementById('instruction-text');
const logo = document.getElementById('logo');
const highScoreText = document.getElementById('highScore');
const gridSize = 20;
let snake = [{ x: 10, y: 10 }];
let highScore = 0;
let food = generateFood();
let direction = 'right';
let gameSpeedDelay = 200;
let gameStarted = false;
function startGame() {
gameStarted = true; // Set gameStarted to true when the game starts
instructionText.style.display = 'none'; // Hide the instruction text
logo.style.display = 'none'; // Hide the instruction text
gameInterval = setInterval(() => {
move();
checkCollision();
draw();
}, gameSpeedDelay);
}
function stopGame() {
clearInterval(gameInterval);
gameStarted = false;
instructionText.style.display = 'block';
logo.style.display = 'block';
}
function draw() {
board.innerHTML = ''; // Clear the board
drawSnake();
drawFood();
updateScore();
}
function drawSnake() {
snake.forEach((segment) => {
const snakeElement = createGameElement('div', 'snake');
setPosition(snakeElement, segment);
board.appendChild(snakeElement);
});
}
function drawFood() {
const foodElement = createGameElement('div', 'food');
setPosition(foodElement, food);
board.appendChild(foodElement);
}
function createGameElement(tag, className) {
const element = document.createElement(tag);
element.className = className;
return element;
}
function setPosition(element, position) {
element.style.gridColumn = position.x;
element.style.gridRow = position.y;
}
// Generate food without taking into account snake position
// function generateFood() {
// const x = Math.floor(Math.random() * gridSize) + 1;
// const y = Math.floor(Math.random() * gridSize) + 1;
// return { x, y };
// }
function generateFood() {
let newFood;
do {
newFood = {
x: Math.floor(Math.random() * gridSize) + 1,
y: Math.floor(Math.random() * gridSize) + 1,
};
} while (isFoodOnSnake(newFood));
return newFood;
}
function isFoodOnSnake(food) {
return snake.some(
(segment) => segment.x === food.x && segment.y === food.y
);
}
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);
// console.log('Head Position:', head);
if (head.x === food.x && head.y === food.y) {
food = generateFood();
increaseSpeed();
// console.log(gameSpeedDelay);
clearInterval(gameInterval);
gameInterval = setInterval(() => {
move();
checkCollision();
draw();
}, gameSpeedDelay);
} else {
snake.pop();
}
}
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 handleKeyPress(event) {
// console.log(event.key);
if (
(!gameStarted && event.code === 'Space') ||
(!gameStarted && event.key === ' ')
) {
startGame(); // Start the game on Enter key press
} else {
switch (event.key) {
case 'ArrowUp':
direction = 'up';
break;
case 'ArrowDown':
direction = 'down';
break;
case 'ArrowLeft':
direction = 'left';
break;
case 'ArrowRight':
direction = 'right';
break;
}
}
}
document.addEventListener('keydown', handleKeyPress);
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();
}
}
}
function updateScore() {
const currentScore = snake.length - 1;
score.textContent = currentScore.toString().padStart(3, '0');
}
function updateHighScore() {
const currentScore = snake.length - 1;
if (currentScore > highScore) {
highScore = currentScore;
highScoreText.textContent = highScore.toString().padStart(3, '0');
}
highScoreText.style.display = 'block';
}
function resetGame() {
updateHighScore();
stopGame();
snake = [{ x: 10, y: 10 }];
food = generateFood();
direction = 'right';
gameSpeedDelay = 200;
updateScore(); // Calling this last because we need to call it under the rest of snake variable
}
});

126
script.js
View File

@@ -1,60 +1,55 @@
// 1) Define DOM elements from HTML. 1 // Define HTML elements
const board = document.getElementById('game-board'); // 1 const board = document.getElementById('game-board');
const instructionText = document.getElementById('instruction-text'); // 12 const instructionText = document.getElementById('instruction-text');
const logo = document.getElementById('logo'); // 12 const logo = document.getElementById('logo');
const score = document.getElementById('score'); // 17 const score = document.getElementById('score');
const highScoreText = document.getElementById('highScore'); // 19 const highScoreText = document.getElementById('highScore');
// Define game variables // Define game variables
const gridSize = 20; // 7 const gridSize = 20;
let snake = [{ x: 10, y: 10 }]; // 2 let snake = [{ x: 10, y: 10 }];
let food = generateFood(); // 6 let food = generateFood();
let highScore = 0; // 19 let highScore = 0;
let direction = 'right'; // 9 let direction = 'right';
let gameInterval; let gameInterval;
let gameSpeedDelay = 200; // 11 let gameSpeedDelay = 200;
let gameStarted = false; // 12 let gameStarted = false;
// 1) Draw game map, snake and food // Draw game map, snake, food
function draw() { function draw() {
board.innerHTML = ''; // Clear the board in case game has started previously. board.innerHTML = '';
drawSnake(); // 2) Draw snake drawSnake();
drawFood(); // 6 Draw food drawFood();
updateScore(); updateScore();
} }
// 2) Draw snake function // Draw snake
function drawSnake() { function drawSnake() {
snake.forEach((segment) => { snake.forEach((segment) => {
const snakeElement = createGameElement('div', 'snake'); // 3 const snakeElement = createGameElement('div', 'snake');
setPosition(snakeElement, segment); // 4 setPosition(snakeElement, segment);
board.appendChild(snakeElement); // 5 board.appendChild(snakeElement);
}); });
} }
// 3) Create a snake or food cube // Create a snake or food cube/div
function createGameElement(tag, className) { function createGameElement(tag, className) {
const element = document.createElement(tag); const element = document.createElement(tag);
element.className = className; element.className = className;
return element; return element;
} }
// 4) Set the position of snake or food // Set the position of snake or food
function setPosition(element, position) { function setPosition(element, position) {
element.style.gridColumn = position.x; // Using CSS gridColumn property to position the cube element.style.gridColumn = position.x;
element.style.gridRow = position.y; element.style.gridRow = position.y;
} }
// 5 Call draw as test // Testing draw function
// draw(); // draw();
// 6) Draw food function // Draw food function
function drawFood() { function drawFood() {
// 20) INITIAL WAY BEFORE END TWEAK TO REMOVE FOOD RENDERING BEFORE START
// const foodElement = createGameElement('div', 'food');
// setPosition(foodElement, food);
// board.appendChild(foodElement);
if (gameStarted) { if (gameStarted) {
const foodElement = createGameElement('div', 'food'); const foodElement = createGameElement('div', 'food');
setPosition(foodElement, food); setPosition(foodElement, food);
@@ -62,21 +57,19 @@ function drawFood() {
} }
} }
// 7) Initial way to generate food without taking into account snake position // Generate food
function generateFood() { function generateFood() {
const x = Math.floor(Math.random() * gridSize) + 1; const x = Math.floor(Math.random() * gridSize) + 1;
const y = Math.floor(Math.random() * gridSize) + 1; const y = Math.floor(Math.random() * gridSize) + 1;
return { x, y }; return { x, y };
} }
// 8) Moving the snake function // Moving the snake
function move() { function move() {
const head = { ...snake[0] }; // Spread operator creates shalow copy and does not alter the original snake[0] object const head = { ...snake[0] };
switch ( switch (direction) {
direction // 9
) {
case 'up': case 'up':
head.y--; // starts at 1 from top. head.y--;
break; break;
case 'down': case 'down':
head.y++; head.y++;
@@ -89,52 +82,50 @@ function move() {
break; break;
} }
snake.unshift(head); // Adding head object to beginning of snake array. snake.unshift(head);
// snake.pop(); 10) Testing move function // snake.pop();
if (head.x === food.x && head.y === food.y) { if (head.x === food.x && head.y === food.y) {
food = generateFood(); // Call function again to replace food position food = generateFood();
increaseSpeed(); // 14) MAKE START GAME FUNCTION FIRST! Increase game speed increaseSpeed();
clearInterval(gameInterval); // Clear past interval clearInterval(gameInterval); // Clear past interval
gameInterval = setInterval(() => { gameInterval = setInterval(() => {
// The interval ensures the continuous execution of the game loop, preventing it from blocking the event loop and allowing for smooth updates after the snake eats food. Else the game stops when eating food.
move(); move();
checkCollision(); // 15 checkCollision();
draw(); draw();
}, gameSpeedDelay); // 11) }, gameSpeedDelay);
} else { } else {
snake.pop(); // Removing last object inside snake array, if food is not eated. snake.pop();
} }
} }
// 10) Testing the move function // Test moving
// setInterval(() => { // setInterval(() => {
// move(); // Move first // move(); // Move first
// draw(); // Then draw again new position // draw(); // Then draw again new position
// }, 200); // The interval time in ms // }, 200);
// 12) Start game function // Start game function
function startGame() { function startGame() {
gameStarted = true; // Keep track of running game gameStarted = true; // Keep track of a running game
instructionText.style.display = 'none'; // Hide text and logo on start instructionText.style.display = 'none';
logo.style.display = 'none'; logo.style.display = 'none';
gameInterval = setInterval(() => { gameInterval = setInterval(() => {
move(); move();
checkCollision(); checkCollision();
draw(); // REMEMBER to comment out DRAW TEST on line 48! draw();
}, gameSpeedDelay); }, gameSpeedDelay);
} }
// 13) Keypresses // Keypress event listener
function handleKeyPress(event) { function handleKeyPress(event) {
if ( if (
(!gameStarted && event.code === 'Space') || (!gameStarted && event.code === 'Space') ||
(!gameStarted && event.key === ' ') (!gameStarted && event.key === ' ')
) { ) {
startGame(); // Start game on enter key press startGame();
} else { } else {
// Change direction variable based on arrows
switch (event.key) { switch (event.key) {
case 'ArrowUp': case 'ArrowUp':
direction = 'up'; direction = 'up';
@@ -154,9 +145,8 @@ function handleKeyPress(event) {
document.addEventListener('keydown', handleKeyPress); document.addEventListener('keydown', handleKeyPress);
// 14)
function increaseSpeed() { function increaseSpeed() {
// console.log('speed'); // just to have the function before start // console.log(gameSpeedDelay);
if (gameSpeedDelay > 150) { if (gameSpeedDelay > 150) {
gameSpeedDelay -= 5; gameSpeedDelay -= 5;
} else if (gameSpeedDelay > 100) { } else if (gameSpeedDelay > 100) {
@@ -168,17 +158,13 @@ function increaseSpeed() {
} }
} }
// 15)
function checkCollision() { function checkCollision() {
// console.log('collision'); // just to have the function before start
const head = snake[0]; const head = snake[0];
// Check if snake hits walls
if (head.x < 1 || head.x > gridSize || head.y < 1 || head.y > gridSize) { if (head.x < 1 || head.x > gridSize || head.y < 1 || head.y > gridSize) {
resetGame(); resetGame();
} }
// Check if snake hits itself
for (let i = 1; i < snake.length; i++) { for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) { if (head.x === snake[i].x && head.y === snake[i].y) {
resetGame(); resetGame();
@@ -186,32 +172,28 @@ function checkCollision() {
} }
} }
// 16)
function resetGame() { function resetGame() {
updateHighScore(); // 19) updateHighScore();
stopGame(); // 18) stopGame();
snake = [{ x: 10, y: 10 }]; snake = [{ x: 10, y: 10 }];
food = generateFood(); food = generateFood();
direction = 'right'; direction = 'right';
gameSpeedDelay = 200; gameSpeedDelay = 200;
updateScore(); // 17) updateScore();
} }
// 17) REMEMBER TO CALL FUNCTION ON LINE 23!
function updateScore() { function updateScore() {
const currentScore = snake.length - 1; // -1 is added otherwise it would start at 1 const currentScore = snake.length - 1;
score.textContent = currentScore.toString().padStart(3, '0'); score.textContent = currentScore.toString().padStart(3, '0');
} }
// 18)
function stopGame() { function stopGame() {
clearInterval(gameInterval); // We need to stop it else snake keeps moving. clearInterval(gameInterval);
gameStarted = false; // We need to set it to false so we can start the game with enter again gameStarted = false;
instructionText.style.display = 'block'; instructionText.style.display = 'block';
logo.style.display = 'block'; logo.style.display = 'block';
} }
// 19)
function updateHighScore() { function updateHighScore() {
const currentScore = snake.length - 1; const currentScore = snake.length - 1;
if (currentScore > highScore) { if (currentScore > highScore) {
@@ -220,5 +202,3 @@ function updateHighScore() {
} }
highScoreText.style.display = 'block'; highScoreText.style.display = 'block';
} }
// 20) Tweak food rendering on line 52

View File

@@ -35,7 +35,7 @@ body,
.game-border-3 { .game-border-3 {
border: #8b966c solid 30px; border: #8b966c solid 30px;
border-radius: 20px; border-radius: 20px;
box-shadow: inset 0 0 0 5px #5b6448; box-shadow: inset 0 0 0 5px #8b966c;
} }
#instruction-text { #instruction-text {
@@ -76,7 +76,6 @@ body,
} }
.snake { .snake {
background-color: #414141;
border: #5a5a5a 1px dotted; border: #5a5a5a 1px dotted;
} }