Work 20. Feb 2020

This commit is contained in:
2020-02-20 10:24:21 +01:00
parent a16a01e417
commit caa65726b9
2 changed files with 116 additions and 39 deletions
html/tasks/chapter_10/snake

@@ -16,6 +16,7 @@
<canvas id="game"></canvas> <canvas id="game"></canvas>
<button class="big" id="start">Start game</button> <button class="big" id="start">Start game</button>
<button class="big" id="reset">Reset</button>
score: <span id="score"></span> Highscore: <span id="highscore"></span> score: <span id="score"></span> Highscore: <span id="highscore"></span>
<form id="pixelAmountForm"> <form id="pixelAmountForm">
<label for="pixelAmount">Size of map:</label> <label for="pixelAmount">Size of map:</label>

@@ -2,8 +2,8 @@
const pixelSize = 20; //Cannot be odd const pixelSize = 20; //Cannot be odd
let pixelAmount = 20; let pixelAmount = 20;
let score = 0; let score = 0;
if (localStorage.highscore) { if (window.localStorage.highscore) {
var highscore = localStorage.highscore; //TODO: global let inside if statement? var highscore = window.localStorage.highscore; //TODO: global let inside if statement?
} else { } else {
highscore = 0; highscore = 0;
} }
@@ -11,10 +11,16 @@ if (localStorage.highscore) {
/* Register HTML DOM elements by variables */ /* Register HTML DOM elements by variables */
const canvas = document.getElementById('game'); const canvas = document.getElementById('game');
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext('2d');
const startButton = document.getElementById('start'); //TODO: Add canvas size selector, score, higscore, const startButton = document.getElementById('start');
const resetButton = document.getElementById('reset');
const scoreSpan = document.getElementById('score');
const highscoreSpan = document.getElementById('highscore');
const pixelAmountInput = document.getElementById('pixelAmount'); const pixelAmountInput = document.getElementById('pixelAmount');
const pixelAmountForm = document.getElementById('pixelAmountForm'); const pixelAmountForm = document.getElementById('pixelAmountForm');
scoreSpan.innerHTML = score;
highscoreSpan.innerHTML = highscore;
/* Initialize HTML */ /* Initialize HTML */
canvas.style.display = 'block'; canvas.style.display = 'block';
ctx.canvas.width = ctx.canvas.height = (pixelAmount + 1) * pixelSize; ctx.canvas.width = ctx.canvas.height = (pixelAmount + 1) * pixelSize;
@@ -30,21 +36,7 @@ const snake = {
[1, 0], [1, 0],
[0, 0], [0, 0],
], ],
deadTail: [0, 0],
/* Draw the snake by the tail array */
draw() {
ctx.fillStyle = this.color;
const clearPosition = this.tail.pop().map(point => point * pixelSize);
ctx.clearRect(clearPosition[0], clearPosition[1], pixelSize, pixelSize);
for (let tailPoint = 0; tailPoint < this.tail.length; tailPoint++) {
/* Correct tailpoint x and y to actual size */
const realPosition = this.tail[tailPoint].map(point => point * pixelSize);
ctx.fillRect(realPosition[0], realPosition[1], pixelSize, pixelSize);
}
},
/* Generate the next tail array */ /* Generate the next tail array */
updateTail() { updateTail() {
@@ -63,6 +55,27 @@ const snake = {
this.tail.unshift([this.tail[0][0], this.tail[0][1] + 1]); this.tail.unshift([this.tail[0][0], this.tail[0][1] + 1]);
break; break;
} }
this.deadTail = this.tail.pop();
},
/* Draw the snake by the tail array */
draw() {
ctx.fillStyle = this.color;
const clearPosition = this.deadTail.map(point => point * pixelSize);
ctx.clearRect(clearPosition[0], clearPosition[1], pixelSize, pixelSize);
for (let tailPoint = 0; tailPoint < this.tail.length; tailPoint++) {
/* Correct tailpoint x and y to actual size */
const realPosition = this.tail[tailPoint].map(point => point * pixelSize);
ctx.fillRect(realPosition[0], realPosition[1], pixelSize, pixelSize);
}
},
addTail() {
this.tail.push[this.deadTail];
}, },
tailCrossing() { tailCrossing() {
@@ -75,11 +88,14 @@ const apple = {
position: [Math.floor(pixelAmount / 2), Math.floor(pixelAmount / 2)], position: [Math.floor(pixelAmount / 2), Math.floor(pixelAmount / 2)],
color: 'red', color: 'red',
/* Sets position to the middle based on pixelAmount */
setStartPosition() {
this.position = [Math.floor(pixelAmount / 2), Math.floor(pixelAmount / 2)];
},
/* Generate new coordinates */ /* Generate new coordinates */
generatePosition() { generatePosition() {
this.position = this.position.map( this.position = game.getClearSpotRandom(); //TODO: Switch between the functions based on how much the snake has eaten
() => Math.floor(Math.random() * pixelAmount) //TODO: Don't put the apple on top of the snake
);
console.debug(`%cApple position: ${this.position}`, 'color: red'); console.debug(`%cApple position: ${this.position}`, 'color: red');
}, },
@@ -95,7 +111,8 @@ const apple = {
/* Handles everything that happens on the canvas */ /* Handles everything that happens on the canvas */
const game = { const game = {
fps: 5, fps: 5,
over: false, hasEnded: false,
isPaused: false,
/* Game init function */ /* Game init function */
init() { init() {
@@ -108,9 +125,10 @@ const game = {
snake.updateTail(); snake.updateTail();
snake.draw(); snake.draw();
if (JSON.stringify(snake.tail[0]) === JSON.stringify(apple.position)) { if (snake.tail[0].toString() === apple.position.toString()) {
console.debug('Snake ate apple'); console.debug('Snake ate apple');
score += 1; score += 1;
scoreSpan.innerHTML = score;
snake.updateTail(); snake.updateTail();
apple.generatePosition(); apple.generatePosition();
apple.draw(); apple.draw();
@@ -122,28 +140,84 @@ const game = {
snake.tail[0][1] < 0 || snake.tail[0][1] < 0 ||
snake.tailCrossing() snake.tailCrossing()
) { ) {
this.over = true; this.hasEnded = true;
} }
}, },
reset() {
/*TODO: get board size from localstorage */
snake.tail = [
[3, 0],
[2, 0],
[1, 0],
[0, 0],
];
snake.direction = 'right';
apple.setStartPosition();
game.hasEnded = false;
ctx.fillStyle = '#ffffff';
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
},
/* Function to determine whether a coordinate hits the snake
* Retuns a bool
*/
hitsSnake(coordinate) {
return snake.tail
.map(snakeCoordinate => snakeCoordinate.toString()) //TODO: Rewrite
.toString()
.includes(coordinate.toString());
},
/* Function to be used if the snake is covering a small part of the map
* Returns a coordinate array
*/
getClearSpotRandom() {
while (true) {
const coordinate = Array.from({length: 2}, () =>
Math.floor(Math.random() * pixelAmount)
);
if (!this.hitsSnake(coordinate)) {
return coordinate;
}
}
},
/* Function to be used if the snake is covering a big part of the map
* Returns a coordinate array
*/
getClearSpotForce() {
clearSpots = [];
for (let x = 0; x < pixelAmount; x++) {
for (let y = 0; y < pixelAmount; y++) {
if (!this.hitsSnake([x, y])) {
clearSpots.push([x, y]);
}
}
}
return clearSpots[Math.floor(Math.random() * clearSpots.length)];
},
}; };
/* Wrapper function requesting a gameloop */ /* Wrapper function requesting a gameloop */
function getLoop() { function getLoop() {
/* Slow down loop by game fps */ /* Slow down loop by game fps */
setTimeout(() => { if (!game.hasEnded) {
window.requestAnimationFrame(getLoop); setTimeout(() => {
game.loop(); window.requestAnimationFrame(getLoop);
game.loop();
}, 1000 / game.fps);
} else {
console.debug('Game over');
if (game.over) { if (score > highscore) {
console.debug('Game over'); //TODO: Exit game loop properly console.debug('New highcore');
highscore = score;
if (score > highscore) { window.localStorage.setItem('highscore', highscore);
console.debug('New highcore');
highscore = score;
window.localStorage.setItem('highscore', highscore);
}
} }
}, 1000 / game.fps); }
} }
/* Add event listeners */ /* Add event listeners */
@@ -156,6 +230,7 @@ startButton.addEventListener(
}, },
false false
); );
resetButton.addEventListener('click', game.reset, false);
pixelAmountForm.addEventListener('submit', updatePixelAmount, false); pixelAmountForm.addEventListener('submit', updatePixelAmount, false);
/* Updates size of canvas */ /* Updates size of canvas */
@@ -164,10 +239,11 @@ function updatePixelAmount(evt) {
pixelAmount = parseInt(pixelAmountInput.value); pixelAmount = parseInt(pixelAmountInput.value);
console.debug('Updated canvas size'); console.debug('Updated canvas size');
ctx.canvas.width = ctx.canvas.height = (pixelAmount + 1) * pixelSize; ctx.canvas.width = ctx.canvas.height = (pixelAmount + 1) * pixelSize;
apple.setStartPosition();
} }
/* Clear higscore from localStorage */ /* Clear higscore from localStorage */
const clearHighscore = () => (localStorage.highscore = 0); const clearHighscore = () => (window.localStorage.highscore = 0);
/* Update direction for snake */ /* Update direction for snake */
function updateDirection(evt) { function updateDirection(evt) {
@@ -200,7 +276,7 @@ function updateDirection(evt) {
snake.direction = 'down'; snake.direction = 'down';
} }
break; break;
//TODO: Add pause function
} }
//TODO: Add pause function
} }