From 530260ac54710b5b25224bb07097f8251acfdcdf Mon Sep 17 00:00:00 2001 From: Nathan DECHER Date: Mon, 6 Apr 2020 15:17:21 +0200 Subject: [PATCH] added decaying fruit --- Makefile | 2 +- levels/arcade-arcade.json | 3 ++- src/js/assets.js | 4 ++- src/js/snek.js | 57 ++++++++++++++++++++++++++++++++++++++- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 8f8dc79..548a210 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ .PHONY: all clean FIRE_ANIM = $(foreach angle, $(shell seq 0 6 359), build/fire$(angle).png) -PEACH_DECAY_ANIM = $(foreach percent, $(shell seq 100 -1 0), build/peach-decay$(percent).png) +PEACH_DECAY_ANIM = $(foreach percent, $(shell seq 99 -1 0), build/peach-decay$(percent).png) PEACH_RAINBOW_ANIM = $(foreach percent, $(shell seq 100 2 299), build/peach-rainbow$(percent).png) IMAGES = $(foreach name, apple wall, public/assets/$(name)32.png) diff --git a/levels/arcade-arcade.json b/levels/arcade-arcade.json index 29319b1..e573367 100644 --- a/levels/arcade-arcade.json +++ b/levels/arcade-arcade.json @@ -10,6 +10,7 @@ [16, 10] ], "rules": { - "superFruitGrow": true + "superFruitGrow": true, + "decayingFruitGrow": true } } diff --git a/src/js/assets.js b/src/js/assets.js index 211fa74..d034467 100644 --- a/src/js/assets.js +++ b/src/js/assets.js @@ -3,6 +3,7 @@ const ProgressBar=require('progress'); const assetSpecs=[ { name: 'fruit', filename: 'apple32.png', type: 'image' }, { name: 'superFruit', filename: 'peach-rainbow-anim.png', type: 'image' }, + { name: 'decayFruit', filename: 'peach-decay-anim.png', type: 'image' }, { name: 'wall', filename: 'wall32.png', type: 'image' }, { name: 'hole', filename: 'hole-ts.png', type: 'image' }, { name: 'fire', filename: 'fire-anim.png', type: 'image' }, @@ -15,7 +16,8 @@ const assetSpecs=[ const tasks=[ { from: 'hole', type: 'tileset', steps: 3, tiles: ['base', 'ul', 'dr', 'dl', 'ur', 'l', 'r', 'd', 'u'] }, { from: 'fire', type: 'animation', steps: 6 }, - { from: 'superFruit', type: 'animation', steps: 5 } + { from: 'superFruit', type: 'animation', steps: 5 }, + { from: 'decayFruit', type: 'animation', steps: 5 } ]; const cvs=document.createElement('canvas'); diff --git a/src/js/snek.js b/src/js/snek.js index 792b537..bd6a08e 100644 --- a/src/js/snek.js +++ b/src/js/snek.js @@ -1,4 +1,4 @@ -const [EMPTY, FOOD, SUPER_FOOD, WALL, FIRE, HOLE, HOLE_S, SNAKE]=Array(7).keys(); +const [EMPTY, FOOD, SUPER_FOOD, DECAY_FOOD, WALL, FIRE, HOLE, HOLE_S, SNAKE]=Array(255).keys(); class SnekGame { constructor(settings, canvas, rules) { @@ -18,6 +18,7 @@ class SnekGame { case ' ': return EMPTY; case 'f': return FOOD; case 'F': return SUPER_FOOD; + case 'd': return DECAY_FOOD; case 'w': return WALL; case 'o': return HOLE; case 'i': return FIRE; @@ -37,6 +38,15 @@ class SnekGame { if(c==FOOD) this.fruits.push([x, y]); } )); + + // extract the decaying fruits + this.decayFood=[]; + this.world + .forEach((l, x) => l.forEach( + (c, y) => { + if(c==DECAY_FOOD) this.decaying.push([x, y, 0]); + } + )); } else { // dimension and objects // get the dimensions @@ -64,6 +74,14 @@ class SnekGame { // add the super food if(settings.superFood) settings.superFood.forEach(([x, y]) => this.world[x][y]=SUPER_FOOD); + + // add the decaying food + if(settings.decayFood) { + settings.decayFood.forEach(([x, y]) => this.world[x][y]=DECAY_FOOD); + this.decayFood=settings.decayFood.map(([x, y]) => [x, y, 0]); + } else { + this.decayFood=[]; + } } // add the snake to the world @@ -93,6 +111,7 @@ class SnekGame { this.rules=Object.assign({ fruitRegrow: true, superFruitGrow: false, + decayingFruitGrow: false, speedIncrease: true, worldWrap: true, winCondition: 'none', @@ -151,6 +170,7 @@ class SnekGame { const hole=assets.get('hole'); const fire=assets.get('fire'); const superFruit=assets.get('superFruit'); + const decayFruit=assets.get('decayFruit'); const putTile=(x, y, tile) => this.ctx.drawImage( tile, offsetX+cellSize*x, @@ -161,6 +181,9 @@ class SnekGame { const putTileAnim=(x, y, tile) => putTile(x, y, tile[ Math.floor(Date.now()/1000*60+x+y)%tile.length ]); + const putTileAnimPercent=(x, y, tile, percent) => putTile(x, y, tile[ + Math.min(Math.round(percent*tile.length), tile.length-1) + ]); const checkAdj=(x, y) => { let adj={}; adj.u=this.world[x][y-1]; @@ -204,6 +227,11 @@ class SnekGame { } } + // draw our decaying fruits + this.decayFood.forEach(([x, y, birth]) => + putTileAnimPercent(x, y, decayFruit, (this.playTime-birth)/2000) + ); + // draw our snake const snake=assets.get('snake'); this.ctx.fillStyle=snake.color; @@ -377,6 +405,14 @@ class SnekGame { this.score+=10; break; + // you eat, you get a small score boost + case DECAY_FOOD: + this.score+=5; + this.decayFood=this.decayFood.filter( + ([x, y, _]) => !(x==head[0] && y==head[1]) + ); + break; + // you eat, you grow case FOOD: // re-grow the snake @@ -421,6 +457,15 @@ class SnekGame { } } + if(this.rules.decayingFruitGrow) { + if(Math.random()<.2) { // 20% chance + const emptyCells=getEmptyCells(); + const cell=emptyCells[Math.floor(Math.random()*emptyCells.length)]; + this.world[cell[0]][cell[1]]=DECAY_FOOD; + this.decayFood.push([cell[0], cell[1], this.playTime]); + } + } + if(this.rules.speedIncrease) { this.delay*=this.rules.speedMultiplier; if(this.delay { + if(this.playTime>=birth+2000) this.world[x][y]=EMPTY; + } + ); + this.decayFood=this.decayFood.filter( + ([_, __, birth]) => this.playTime50 && this.tickId%this.rules.autoSpeadIncreaseTicks==0) this.delay--;