|
|
|
@ -1,4 +1,4 @@ |
|
|
|
|
const [EMPTY, FOOD, WALL, FIRE, HOLE, HOLE_S, SNAKE]=Array(7).keys(); |
|
|
|
|
const [EMPTY, FOOD, SUPER_FOOD, WALL, FIRE, HOLE, HOLE_S, SNAKE]=Array(7).keys(); |
|
|
|
|
|
|
|
|
|
class SnekGame { |
|
|
|
|
constructor(settings, canvas, rules) { |
|
|
|
@ -17,6 +17,7 @@ class SnekGame { |
|
|
|
|
switch(settings.world[y][x]) { |
|
|
|
|
case ' ': return EMPTY; |
|
|
|
|
case 'f': return FOOD; |
|
|
|
|
case 'F': return SUPER_FOOD; |
|
|
|
|
case 'w': return WALL; |
|
|
|
|
case 'o': return HOLE; |
|
|
|
|
case 'i': return FIRE; |
|
|
|
@ -60,6 +61,9 @@ class SnekGame { |
|
|
|
|
// add the food
|
|
|
|
|
settings.food.forEach(([x, y]) => this.world[x][y]=FOOD); |
|
|
|
|
this.fruits=[...settings.food]; |
|
|
|
|
|
|
|
|
|
// add the super food
|
|
|
|
|
if(settings.superFood) settings.superFood.forEach(([x, y]) => this.world[x][y]=SUPER_FOOD); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// add the snake to the world
|
|
|
|
@ -88,6 +92,7 @@ class SnekGame { |
|
|
|
|
// load the custom rules
|
|
|
|
|
this.rules=Object.assign({ |
|
|
|
|
fruitRegrow: true, |
|
|
|
|
superFruitGrow: false, |
|
|
|
|
speedIncrease: true, |
|
|
|
|
worldWrap: true, |
|
|
|
|
winCondition: 'none', |
|
|
|
@ -145,6 +150,7 @@ class SnekGame { |
|
|
|
|
const wall=assets.get('wall'); |
|
|
|
|
const hole=assets.get('hole'); |
|
|
|
|
const fire=assets.get('fire'); |
|
|
|
|
const superFruit=assets.get('superFruit'); |
|
|
|
|
const putTile=(x, y, tile) => this.ctx.drawImage( |
|
|
|
|
tile, |
|
|
|
|
offsetX+cellSize*x, |
|
|
|
@ -190,6 +196,10 @@ class SnekGame { |
|
|
|
|
// technically, this works for all shapes
|
|
|
|
|
// however, the tileset only handles convex shapes
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
case SUPER_FOOD: |
|
|
|
|
putTileAnim(x, y, superFruit); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -362,7 +372,12 @@ class SnekGame { |
|
|
|
|
) return this.die(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// you eat, you don't die
|
|
|
|
|
// you eat, you get a massive score boost
|
|
|
|
|
case SUPER_FOOD: |
|
|
|
|
this.score+=10; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
// you eat, you grow
|
|
|
|
|
case FOOD: |
|
|
|
|
// re-grow the snake
|
|
|
|
|
this.snake.push(tail); |
|
|
|
@ -377,9 +392,9 @@ class SnekGame { |
|
|
|
|
// increase score
|
|
|
|
|
this.score++; |
|
|
|
|
|
|
|
|
|
// custom rules
|
|
|
|
|
if(this.rules.fruitRegrow) { |
|
|
|
|
const emptyCells=this.world |
|
|
|
|
// list empty cells
|
|
|
|
|
const getEmptyCells=() => |
|
|
|
|
this.world |
|
|
|
|
.map( |
|
|
|
|
(l, x) => l |
|
|
|
|
.map( |
|
|
|
@ -388,11 +403,24 @@ class SnekGame { |
|
|
|
|
a => a |
|
|
|
|
) |
|
|
|
|
).flat(); |
|
|
|
|
|
|
|
|
|
// custom rules
|
|
|
|
|
if(this.rules.fruitRegrow) { |
|
|
|
|
const emptyCells=getEmptyCells(); |
|
|
|
|
|
|
|
|
|
const cell=emptyCells[Math.floor(Math.random()*emptyCells.length)]; |
|
|
|
|
this.fruits.push(cell); |
|
|
|
|
this.world[cell[0]][cell[1]]=FOOD; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(this.rules.superFruitGrow) { |
|
|
|
|
if(Math.random()<.1) { // 10% chance
|
|
|
|
|
const emptyCells=getEmptyCells(); |
|
|
|
|
const cell=emptyCells[Math.floor(Math.random()*emptyCells.length)]; |
|
|
|
|
this.world[cell[0]][cell[1]]=SUPER_FOOD; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(this.rules.speedIncrease) { |
|
|
|
|
this.delay*=this.rules.speedMultiplier; |
|
|
|
|
if(this.delay<this.rules.speedCap) this.delay=this.rules.speedCap; |
|
|
|
|