2022-03-01 18:14:02 +00:00
|
|
|
// get elements from page
|
2022-02-28 20:07:10 +00:00
|
|
|
const info = document.getElementById("info");
|
2022-03-01 18:02:09 +00:00
|
|
|
const highscore = document.getElementById("highscore");
|
2022-02-28 18:48:12 +00:00
|
|
|
const canvas = document.getElementById("canvas");
|
2022-03-01 18:14:02 +00:00
|
|
|
|
2022-02-28 18:48:12 +00:00
|
|
|
const ctx = canvas.getContext("2d");
|
|
|
|
const game = {
|
|
|
|
size: 15,
|
2022-03-01 18:02:09 +00:00
|
|
|
speed: 1000 / 15, // 15 frames per second
|
2022-03-01 18:14:02 +00:00
|
|
|
snek: {
|
2022-02-28 18:48:12 +00:00
|
|
|
body: [
|
2022-02-28 18:59:16 +00:00
|
|
|
[3, 7],
|
|
|
|
[4, 7],
|
|
|
|
[5, 7],
|
|
|
|
[6, 7],
|
2022-02-28 18:48:12 +00:00
|
|
|
[7, 7],
|
|
|
|
],
|
2022-02-28 19:55:41 +00:00
|
|
|
dir: null,
|
|
|
|
newdir: null,
|
2022-02-28 18:48:12 +00:00
|
|
|
},
|
2022-02-28 18:59:16 +00:00
|
|
|
apple: [12, 7],
|
2022-03-01 18:14:02 +00:00
|
|
|
highscore: 0,
|
2022-02-28 18:48:12 +00:00
|
|
|
};
|
2018-03-19 20:11:32 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// reset the game board (but not the highscore)
|
2022-02-28 19:55:41 +00:00
|
|
|
function reset() {
|
|
|
|
game.apple = [12, 7];
|
2022-03-01 18:14:02 +00:00
|
|
|
game.snek.body = [
|
2022-02-28 19:55:41 +00:00
|
|
|
[3, 7],
|
|
|
|
[4, 7],
|
|
|
|
[5, 7],
|
|
|
|
[6, 7],
|
|
|
|
[7, 7],
|
|
|
|
];
|
2022-03-01 18:14:02 +00:00
|
|
|
game.snek.dir = null;
|
|
|
|
game.snek.newdir = null;
|
2022-02-28 19:55:41 +00:00
|
|
|
}
|
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// check if the x and y coordinate is part of the snek
|
2022-03-01 18:14:02 +00:00
|
|
|
function inSnek(x, y) {
|
|
|
|
for (let part of game.snek.body) {
|
2022-02-28 18:59:16 +00:00
|
|
|
if (part[0] === x && part[1] === y) return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// draw the game board
|
2022-02-28 18:48:12 +00:00
|
|
|
function draw() {
|
|
|
|
const size = 25;
|
|
|
|
ctx.clearRect(0, 0, 500, 500);
|
|
|
|
for (let i = 0; i < game.size; i++) {
|
|
|
|
for (let j = 0; j < game.size; j++) {
|
2022-03-01 18:14:02 +00:00
|
|
|
ctx.fillStyle = inSnek(i, j)
|
2022-02-28 19:55:41 +00:00
|
|
|
? "#38e070"
|
|
|
|
: i === game.apple[0] && j === game.apple[1]
|
|
|
|
? "#eb4034"
|
|
|
|
: "#333333";
|
2022-02-28 18:48:12 +00:00
|
|
|
ctx.fillRect(i * size, j * size, size, size);
|
|
|
|
}
|
|
|
|
}
|
2021-05-27 14:34:27 +00:00
|
|
|
}
|
2021-05-26 21:53:06 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// update the game board
|
2022-02-28 18:48:12 +00:00
|
|
|
function update() {
|
2022-03-01 18:14:02 +00:00
|
|
|
game.snek.dir = game.snek.newdir;
|
2022-03-01 18:02:09 +00:00
|
|
|
|
2022-03-01 18:14:02 +00:00
|
|
|
const b = game.snek.body;
|
2022-02-28 19:11:15 +00:00
|
|
|
const l = b[b.length - 1];
|
|
|
|
const next = move();
|
2022-02-28 19:55:41 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// check if the snek ate the apple
|
2022-02-28 19:55:41 +00:00
|
|
|
if (game.apple[0] === next[0] && game.apple[1] === next[1]) {
|
2022-03-01 18:14:02 +00:00
|
|
|
// the apple shouldnt be on top of the snek
|
|
|
|
// try 30 times to place the apple
|
2022-03-01 18:02:09 +00:00
|
|
|
for (let i = 0; i < 30; i++) {
|
|
|
|
const x = Math.floor(Math.random() * game.size);
|
|
|
|
const y = Math.floor(Math.random() * game.size);
|
|
|
|
game.apple = [x, y];
|
2022-03-04 17:25:24 +00:00
|
|
|
|
2022-03-01 18:14:02 +00:00
|
|
|
if (!inSnek(game.apple[0], game.apple[1])) break;
|
2022-03-01 18:02:09 +00:00
|
|
|
}
|
2022-02-28 18:59:16 +00:00
|
|
|
} else {
|
|
|
|
b.shift();
|
|
|
|
}
|
2022-02-28 19:55:41 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// check if the snek crashed into itself
|
2022-03-01 18:14:02 +00:00
|
|
|
if (inSnek(next[0], next[1])) {
|
2022-02-28 19:55:41 +00:00
|
|
|
reset();
|
2022-02-28 19:11:15 +00:00
|
|
|
}
|
2022-02-28 19:55:41 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// check if the snek fell out of the world
|
2022-02-28 19:55:41 +00:00
|
|
|
if (l[0] < 0 || l[0] >= game.size || l[1] < 0 || l[1] >= game.size) {
|
|
|
|
reset();
|
2022-02-28 19:11:15 +00:00
|
|
|
}
|
2022-03-04 17:25:24 +00:00
|
|
|
|
2022-03-02 17:56:29 +00:00
|
|
|
// uncomment to wrap
|
|
|
|
// if (next[0] < 0) next[0] = game.size - 1;
|
|
|
|
// if (next[0] >= game.size) next[0] = 0;
|
|
|
|
// if (next[1] < 0 ) next[1] = game.size - 1;
|
|
|
|
// if (next[1] >= game.size) next[1] = 0;
|
2022-02-28 19:55:41 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
b.push(next); // move the snek
|
2022-03-01 18:02:09 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// update score display
|
2022-03-01 18:14:02 +00:00
|
|
|
if (game.snek.dir !== null) {
|
2022-03-01 18:02:09 +00:00
|
|
|
const score = b.length - 5;
|
2022-03-04 17:25:24 +00:00
|
|
|
if (score > game.highscore) game.highscore = score; // update high score if necessary
|
2022-03-01 18:02:09 +00:00
|
|
|
info.innerText = `${score < 15 ? "length" : "longth"}: ${score}`;
|
2022-03-01 18:26:02 +00:00
|
|
|
highscore.innerText = `highscore: ${game.highscore}\n`;
|
2022-03-01 18:14:02 +00:00
|
|
|
}
|
2022-02-28 18:48:12 +00:00
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// calculate where the snek will move to
|
2022-02-28 18:48:12 +00:00
|
|
|
function move() {
|
2022-02-28 19:11:15 +00:00
|
|
|
const [x, y] = l;
|
2022-03-01 18:14:02 +00:00
|
|
|
switch (game.snek.dir) {
|
2022-02-28 18:48:12 +00:00
|
|
|
case "left":
|
2022-02-28 19:11:15 +00:00
|
|
|
return [x - 1, y];
|
2022-02-28 18:48:12 +00:00
|
|
|
case "right":
|
2022-02-28 19:11:15 +00:00
|
|
|
return [x + 1, y];
|
2022-02-28 18:48:12 +00:00
|
|
|
case "up":
|
2022-02-28 19:11:15 +00:00
|
|
|
return [x, y - 1];
|
2022-02-28 18:48:12 +00:00
|
|
|
case "down":
|
2022-02-28 19:11:15 +00:00
|
|
|
return [x, y + 1];
|
2022-02-28 19:55:41 +00:00
|
|
|
default:
|
|
|
|
return [x, y];
|
2022-02-28 18:48:12 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// change direction on keypress
|
2022-02-28 18:48:12 +00:00
|
|
|
document.addEventListener("keydown", (e) => {
|
2022-03-04 17:25:24 +00:00
|
|
|
if (e.ctrlKey || e.shiftKey) return;
|
|
|
|
|
2022-03-01 18:14:02 +00:00
|
|
|
const s = game.snek;
|
|
|
|
if (s.dir !== s.newdir) update(); // avoid snek from crashing into itself
|
2022-03-04 17:25:24 +00:00
|
|
|
e.preventDefault();
|
2022-02-28 18:48:12 +00:00
|
|
|
switch (e.key) {
|
2022-02-28 18:59:16 +00:00
|
|
|
case "ArrowLeft":
|
2022-02-28 19:55:41 +00:00
|
|
|
return s.dir !== "right" ? (s.newdir = "left") : 0;
|
2022-02-28 18:59:16 +00:00
|
|
|
case "ArrowRight":
|
2022-02-28 19:55:41 +00:00
|
|
|
return s.dir !== "left" ? (s.newdir = "right") : 0;
|
2022-02-28 18:59:16 +00:00
|
|
|
case "ArrowUp":
|
2022-02-28 19:55:41 +00:00
|
|
|
return s.dir !== "down" ? (s.newdir = "up") : 0;
|
2022-02-28 18:59:16 +00:00
|
|
|
case "ArrowDown":
|
2022-02-28 19:55:41 +00:00
|
|
|
return s.dir !== "up" ? (s.newdir = "down") : 0;
|
2022-02-28 18:48:12 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-02-28 20:07:10 +00:00
|
|
|
// the main game loop
|
2022-02-28 18:59:16 +00:00
|
|
|
setInterval(() => {
|
|
|
|
update();
|
|
|
|
draw();
|
2022-03-01 18:02:09 +00:00
|
|
|
}, game.speed);
|