-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsketch.js
255 lines (206 loc) · 4.75 KB
/
sketch.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
// Julian Kandlhofer, Mar 2018
// SNAKE, A copy of the classic snake game
const scl = 25;
let snake;
// Coordinates of the food
let apple;
// Nuber of cells in x and y direction
let x_cells;
let y_cells;
let pauseButton;
let startButton;
// DOM elements
let resetBtn;
// Snake class
class Snake {
constructor() {
this.reset();
}
// Draw snake to the screen
draw() {
noStroke();
fill(255);
rect(this.pos.x * scl, this.pos.y * scl, scl, scl);
this.tail.forEach(el => {
noStroke();
fill(255,255,0);
rect(el.x * scl, el.y * scl, scl, scl);
});
}
// Set direction of the snake
move(x,y) {
if(this.tail.length>0)
{
if(x === 1 && this.dir.x === -1) {
x = -1;
}
else if(x === -1 && this.dir.x === 1) {
x = 1;
}
else if(y === 1 && this.dir.y === -1) {
y = -1;
}
else if(y === -1 && this.dir.y === 1) {
y = 1;
}
}
this.dir.x = x;
this.dir.y = y;
}
// Check if the snake has collided with the boders or itself
checkCollision() {
let coll = false;
if(
this.pos.x < 0 ||
this.pos.x >= x_cells ||
this.pos.y < 0 ||
this.pos.y >= y_cells
)
{
coll = true;
}
this.tail.forEach(t => {
if(t.equals(this.pos))
{
coll = true;
}
});
return coll;
}
// Update Position of rhe snake
update() {
// The snake has a tail or has just eaten
if(this.tail.length>0 || this.hasEaten) {
// If it hasnt eaten remove the last element
// When it has, just keep it to increase the length
if(!this.hasEaten) {
this.tail.pop();
}
this.hasEaten = false;
// Add the current position of the snake to the beginning
this.tail.unshift(createVector(this.pos.x, this.pos.y));
}
// Move the current position
this.pos.x += this.dir.x;
this.pos.y += this.dir.y;
}
// Check if the head is in the same location as the fruit
eat(fruit) {
if(dist(fruit.x,fruit.y, this.pos.x, this.pos.y) < 1) {
this.hasEaten = true;
return true;
} else {
return false;
}
}
// Returns tail length as score
getScore() {
return this.tail.length;
}
// Resets the snake
reset() {
// Position of the head of the snake
this.pos = createVector(x_cells/2, y_cells/2);
// Direction the head is moving in
this.dir = createVector(0,1);
// Stores location of all the tail cells
this.tail = [];
// Stores if the snake has just eaten a fruit
// in the next draw cycle the snake will be lengthend and this will be reset
this.hasEaten = false;
}
}
// Setup function, runs once
function setup() {
let cnv = createCanvas(600, 600);
cnv.parent('canvasContainer');
frameRate(10);
x_cells = Math.floor(width/scl);
y_cells = Math.floor(height/scl);
resetBtn = document.getElementById('resetButton');
resetBtn.addEventListener('click', resetGame);
updateHS();
fill(255);
noStroke();
snake = new Snake();
apple = newFoodPos();
}
// Draw loop
function draw() {
background(51);
// LOGIC
if (snake.eat(apple)) {
apple = newFoodPos();
}
snake.update();
if(snake.checkCollision()) {
gameOver();
}
document.getElementById('score').innerHTML = 'Score: ' + snake.getScore();
///// DRAWING
// APPLE
fill(255,0,0);
noStroke();
rect(apple.x * scl ,apple.y * scl, scl, scl);
// SNAKE
snake.draw();
}
// Generate a new position for the food
function newFoodPos() {
return createVector(Math.floor(random(0,x_cells)),Math.floor(random(0,y_cells)));
}
// Handle keyboard input
function keyPressed() {
switch(keyCode)
{
case UP_ARROW:
setTimeout(() => {
snake.move(0,-1);
}, 0);
break;
case DOWN_ARROW:
setTimeout(() => {
snake.move(0,1);
}, 0);
break;
case LEFT_ARROW:
setTimeout(() => {
snake.move(-1,0);
}, 0);
break;
case RIGHT_ARROW:
setTimeout(() => {
snake.move(1,0);
}, 0);
break;
}
}
// Called when gameover
function gameOver() {
noLoop();
background(255,0,0,150);
let currScore = snake.getScore();
updateHS(currScore);
}
// Restarts the game after gameover
function resetGame() {
snake.reset();
apple = newFoodPos();
loop();
}
// Updates Highscore display
function updateHS(score) {
// Load last hs from local storage
let hs = localStorage.getItem('highscore');
if(hs) {
if( hs < score){
localStorage.setItem('highscore', score);
hs = score;
}
document.getElementById('highscore').innerHTML = hs;
}
else {
document.getElementById('highscore').innerHTML = '0';
localStorage.setItem('highscore', '0');
}
}