-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
274 lines (248 loc) · 8.3 KB
/
script.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
// Define html elements as variables for easy access in the script file
const board = document.getElementById('game-board');
const instructions = document.getElementById('instruction-text');
const logo = document.getElementById('logo');
const score = document.getElementById('score');
const highScore = document.getElementById('high-score');
const timer = document.getElementById('timer');
// Define game variables
const gridSize = 20; // Size of the game board
let snake = [{ x: 10, y: 10 }]; // Snake starting position
let food = generateFood(); // Food starting position
let direction = 'right'; // Snake starting direction
let gameInterval; // Variable to store the setInterval function
let gameSpeed = 200; // Time between each move in milliseconds
let gameStarted = false;
let time; // Variable to store the setInterval function
// Generate a random position for the food
function generateFood() {
const position = {
x: Math.floor(Math.random() * gridSize) + 1, // Random number between 1 and 20
y: Math.floor(Math.random() * gridSize) + 1,
};
return position;
}
// Create a snake or food element
function createGameElement(tag, className) {
const element = document.createElement(tag);
element.className = className;
return element;
}
// Set the position of a snake or food element
function setPosition(element, position) {
element.style.gridColumn = position.x;
element.style.gridRow = position.y;
}
// Draw the snake on the board
function drawSnake() {
snake.forEach((segment) => {
const snakeElement = createGameElement('div', 'snake');
setPosition(snakeElement, segment);
board.appendChild(snakeElement);
});
}
// Draw the food on the board
function drawFood() {
if (gameStarted) {
const foodElement = createGameElement('div', 'food blink');
setPosition(foodElement, food);
board.appendChild(foodElement);
}
}
// Draw the game board, snake, and food
function draw() {
board.innerHTML = ''; // Clear the board
drawSnake();
drawFood();
updateScore();
}
// Move the snake
function move() {
const head = { ...snake[0] }; // Create a copy of the snake head
switch (direction) {
case 'right':
head.x++; // Move the snake right by incrementing the x position, e.g. from (1, 1) to (2, 1)
break;
case 'left':
head.x--; // e.g. from (1, 1) to (0, 1)
break;
case 'up':
head.y--; // e.g. from (1, 1) to (1, 0)
break;
case 'down':
head.y++; // e.g. from (1, 1) to (1, 2)
break;
default:
break;
}
snake.unshift(head); // add the new head to make it look like it's moving
// Check if the snake has eaten the food
if (head.x === food.x && head.y === food.y) {
food = generateFood();
speed();
clearInterval(gameInterval);
gameInterval = setInterval(() => {
move();
checkCollision();
draw();
}, gameSpeed);
} else {
snake.pop(); // remove the snake in the last position to make it look like it's moving
}
}
// Adjust the game speed
function speed() {
if (gameSpeed > 150) {
gameSpeed -= 5;
} else if (gameSpeed > 100) {
gameSpeed -= 3;
} else if (gameSpeed > 50) {
gameSpeed -= 2;
} else if (gameSpeed > 25) {
gameSpeed -= 1;
}
}
// Check if the snake has hit the wall or itself
function checkCollision() {
const head = snake[0];
if (head.x < 1 || head.x > gridSize || head.y < 1 || head.y > gridSize) {
gameOver();
}
for (let i = 1; i < snake.length; i++) {
if (head.x === snake[i].x && head.y === snake[i].y) {
gameOver();
}
}
}
// Start the game
function startGame() {
gameStarted = true; // keep track of whether the game has started
instructions.style.display = 'none'; // hide the instructions
logo.style.display = 'none'; // hide the logo
speed();
clearInterval(gameInterval);
gameInterval = setInterval(() => {
move();
checkCollision();
draw();
}, gameSpeed);
timerStart();
}
// Update the score
function updateScore() {
const currentScore = snake.length - 1;
score.textContent = currentScore.toString().padStart(4, '0');
}
// Timer
function timerStart() {
let seconds = 0;
let minutes = 0;
let hours = 0;
clearInterval(time);
time = setInterval(() => {
seconds++;
if (seconds === 60) {
seconds = 0;
minutes++;
}
if (minutes === 60) {
minutes = 0;
hours++;
}
timer.textContent = `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
}, 1000);
}
// Update the high score
function updateHighScore() {
highScore.textContent = score.textContent > highScore.textContent ? score.textContent + '👑' : highScore.textContent;
highScore.style.display = 'block';
}
// End the game
function gameOver() {
updateHighScore();
stopGame();
snake = [{ x: 10, y: 10 }]; // reset the snake position
food = generateFood(); // reset the food position
direction = 'right'; // reset the snake direction
gameSpeed = 200; // reset the game speed
}
// Stop the game
function stopGame() {
clearInterval(gameInterval); // stop the game
clearInterval(time); // stop the timer
timer.textContent = '00:00:00'; // reset the timer
gameStarted = false; // reset the gameStarted variable
instructions.style.display = 'block'; // show the instructions
logo.style.display = 'block'; // show the logo
}
// Handle keypresses
function handleKeyPress(event) {
if ((!gameStarted && (event.key === 'Space')) || (!gameStarted) && (event.key === ' ')) {
startGame();
} else {
switch (event.key) {
case 'ArrowRight':
direction = 'right';
break;
case 'ArrowLeft':
direction = 'left';
break;
case 'ArrowUp':
direction = 'up';
break;
case 'ArrowDown':
direction = 'down';
break;
default:
break;
}
}
}
// Handle touch
function handleTouch(event) {
let startX, startY; // Variables to store the start x and y positions of the touch
ontouchstart = event => {
startX = event.touches[0].clientX; // Get the x position of the touch
startY = event.touches[0].clientY; // Get the y position of the touch
if (!gameStarted) { // Start the game if it hasn't started yet
startGame();
}
}
ontouchmove = event => {
const endX = event.touches[0].clientX; // Get the x position of the touch
const endY = event.touches[0].clientY; // Get the y position of the touch
const deltaX = endX - startX; // Calculate the difference between the start and end x positions
const deltaY = endY - startY; // Calculate the difference between the start and end y positions
if (Math.abs(deltaX) > Math.abs(deltaY)) { // Check if the movement is horizontal or vertical
if (deltaX > 0) {
direction = 'right';
} else {
direction = 'left';
}
} else {
if (deltaY < 0) {
direction = 'up';
} else {
direction = 'down';
}
}
}
}
// Snowfall effect
function snow() {
const fragment = document.createDocumentFragment(); // Create a document fragment
for (let i = 0; i < 100; i++) {
let snowflake = document.createElement("div");
snowflake.classList.add("snowflake");
snowflake.style.left = Math.random() * window.innerWidth + "px";
snowflake.style.animationDelay = Math.random() * 5 + "s";
fragment.appendChild(snowflake); // Append snowflakes to the fragment
}
const snow = document.getElementsByClassName("snow")[0]; // Get the snow element
snow.appendChild(fragment); // Append the fragment to the snow element
}
// Start the snowfall effect
snow();
// Add event listeners
document.addEventListener('keydown', handleKeyPress);
document.addEventListener('touchstart', handleTouch);