fixed engine and added level2
This commit is contained in:
+79
-29
@@ -6,21 +6,62 @@ const ifNaN=(v, r) => isNaN(v)?r:v;
|
||||
|
||||
class SnekGame {
|
||||
constructor(settings, canvas, rules) {
|
||||
// build the world
|
||||
this.dimensions=[...settings.dimensions];
|
||||
this.world=Array(settings.dimensions[0]);
|
||||
for(let i=0; i<settings.dimensions[0]; i++) {
|
||||
this.world[i]=Array(settings.dimensions[1]);
|
||||
this.world[i].fill(EMPTY);
|
||||
}
|
||||
console.log(this);
|
||||
settings.walls.forEach(([x, y]) => this.world[x][y]=WALL);
|
||||
settings.food.forEach(([x, y]) => this.world[x][y]=FOOD);
|
||||
settings.snake.forEach(([x, y]) => this.world[x][y]=SNAKE);
|
||||
|
||||
// setup the delay
|
||||
this.delay=settings.delay;
|
||||
|
||||
// world is given in the level
|
||||
if(settings.world) { // explicitly
|
||||
|
||||
// convert the world
|
||||
this.world=Array(settings.world[0].length);
|
||||
for(let x=0; x<this.world.length; x++) {
|
||||
this.world[x]=Array(settings.world.length);
|
||||
for(let y=0; y<this.world[x].length; y++) {
|
||||
this.world[x][y]=(() => {
|
||||
switch(settings.world[y][x]) {
|
||||
case ' ': return EMPTY;
|
||||
case 'f': return FOOD;
|
||||
case 'w': return WALL;
|
||||
}
|
||||
})();
|
||||
}
|
||||
}
|
||||
//
|
||||
// extract the dimensions
|
||||
this.dimensions=[this.world.length, this.world[0].length];
|
||||
|
||||
// extract the fruits
|
||||
this.fruits=[];
|
||||
this.world
|
||||
.forEach((l, x) => l.forEach(
|
||||
(c, y) => {
|
||||
if(c==FOOD) this.fruits.push([x, y]);
|
||||
}
|
||||
));
|
||||
} else { // dimension and objects
|
||||
|
||||
// get the dimensions
|
||||
this.dimensions=[...settings.dimensions];
|
||||
|
||||
// build an empty world
|
||||
this.world=Array(settings.dimensions[0]);
|
||||
for(let i=0; i<settings.dimensions[0]; i++) {
|
||||
this.world[i]=Array(settings.dimensions[1]);
|
||||
this.world[i].fill(EMPTY);
|
||||
}
|
||||
|
||||
// add the walls
|
||||
settings.walls.forEach(([x, y]) => this.world[x][y]=WALL);
|
||||
|
||||
// add the food
|
||||
settings.food.forEach(([x, y]) => this.world[x][y]=FOOD);
|
||||
this.fruits=[...settings.food];
|
||||
}
|
||||
|
||||
// add the snake to the world
|
||||
settings.snake.forEach(([x, y]) => this.world[x][y]=SNAKE);
|
||||
|
||||
|
||||
// get the head and initial direction
|
||||
this.head=[...settings.snake[0]];
|
||||
this.direction=[
|
||||
@@ -28,9 +69,8 @@ class SnekGame {
|
||||
ifNaN(settings.snake[0][1]-settings.snake[1][1], 0)
|
||||
];
|
||||
|
||||
// get the snake and the fruits themselves
|
||||
// store the snake
|
||||
this.snake=[...settings.snake];
|
||||
this.fruits=[...settings.food];
|
||||
|
||||
// get our canvas, like, if we want to actually draw
|
||||
this.canvas=canvas;
|
||||
@@ -43,8 +83,13 @@ class SnekGame {
|
||||
speedIncrease: true,
|
||||
worldWrap: true,
|
||||
winCondition: 'none',
|
||||
scoreSystem: 'fruit'
|
||||
}, rules, settings);
|
||||
scoreSystem: 'fruit',
|
||||
netPlay: false
|
||||
}, rules, settings.rules || {});
|
||||
}
|
||||
|
||||
get playTime() {
|
||||
return Date.now()-this.firstStep;
|
||||
}
|
||||
|
||||
draw() {
|
||||
@@ -121,7 +166,7 @@ class SnekGame {
|
||||
this.ctx.drawImage(
|
||||
fruit,
|
||||
offsetX+cellSize*x+(1-fruitScale)*cellSize/2,
|
||||
offsetY+cellSize*x+(1-fruitScale)*cellSize/2,
|
||||
offsetY+cellSize*y+(1-fruitScale)*cellSize/2,
|
||||
cellSize*fruitScale,
|
||||
cellSize*fruitScale
|
||||
);
|
||||
@@ -163,11 +208,8 @@ class SnekGame {
|
||||
|
||||
// remove the fruit from existence
|
||||
this.world[head[0]][head[1]]=SNAKE;
|
||||
this.fruits.splice(
|
||||
this.fruits.find(
|
||||
([x, y]) => x==head[0] && y==head[1]
|
||||
),
|
||||
1
|
||||
this.fruits=this.fruits.filter(
|
||||
([x, y]) => !(x==head[0] && y==head[1])
|
||||
);
|
||||
|
||||
// custom rules
|
||||
@@ -192,14 +234,22 @@ class SnekGame {
|
||||
this.snake.unshift(head);
|
||||
|
||||
// victory condition
|
||||
if(!this.fruits.length) return this.win();
|
||||
if(this.rules.winCondition=='fruit') {
|
||||
if(!this.fruits.length) return this.win();
|
||||
}
|
||||
if(this.rules.winCondition=='time') {
|
||||
if(this.playTime>=this.rules.gameDuration) return this.win();
|
||||
}
|
||||
if(this.rules.winCondition=='score') {
|
||||
if(this.score>=this.rules.scoreObjective) return this.win();
|
||||
}
|
||||
}
|
||||
|
||||
tick() {
|
||||
if(!this.playing) return;
|
||||
if(!this.lastStep) this.lastStep=this.firstStep;
|
||||
this.draw();
|
||||
if(this.callback) this.callback();
|
||||
if(this.callback) this.callback('tick');
|
||||
if(this.lastStep+this.delay<Date.now()) {
|
||||
this.lastStep+=this.delay;
|
||||
this.step();
|
||||
@@ -209,15 +259,14 @@ class SnekGame {
|
||||
|
||||
win() {
|
||||
this.playing=false;
|
||||
// you gud lol
|
||||
console.log("You gud lol");
|
||||
console.log(`Won in ${(Date.now()-this.firstStep)/1000} seconds`);
|
||||
this.endPlayTime=this.playTime;
|
||||
if(this.callback) this.callback('win');
|
||||
}
|
||||
|
||||
die() {
|
||||
this.playing=false;
|
||||
// you bad lol
|
||||
console.log("You bad lol");
|
||||
this.endPlayTime=this.playTime;
|
||||
if(this.callback) this.callback('die');
|
||||
}
|
||||
|
||||
handleInputs(inputs) {
|
||||
@@ -244,4 +293,5 @@ class SnekGame {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports=SnekGame;
|
||||
return SnekGame;
|
||||
|
||||
Reference in New Issue
Block a user