parent
7b20b0e8ec
commit
7121c230fc
7 changed files with 100 additions and 4 deletions
2
Makefile
2
Makefile
|
@ -9,7 +9,7 @@ PORTAL_C_ANIM = $(foreach angle, $(shell seq 0 6 359), build/portal-c$(angle).pn
|
||||||
PORTAL_D_ANIM = $(foreach angle, $(shell seq 0 6 359), build/portal-d$(angle).png)
|
PORTAL_D_ANIM = $(foreach angle, $(shell seq 0 6 359), build/portal-d$(angle).png)
|
||||||
|
|
||||||
IMAGES = $(foreach name, apple wall oil key door, public/assets/$(name)32.png)
|
IMAGES = $(foreach name, apple wall oil key door, public/assets/$(name)32.png)
|
||||||
TILESETS = $(foreach name, hole, public/assets/$(name)-ts.png)
|
TILESETS = $(foreach name, hole switch spikes, public/assets/$(name)-ts.png)
|
||||||
ANIMATIONS = $(foreach name, fire peach-decay peach-rainbow portal-a portal-b portal-c portal-d, public/assets/$(name)-anim.png)
|
ANIMATIONS = $(foreach name, fire peach-decay peach-rainbow portal-a portal-b portal-c portal-d, public/assets/$(name)-anim.png)
|
||||||
JSON = $(foreach name, snake levelList config metaConfig, public/assets/$(name).json)
|
JSON = $(foreach name, snake levelList config metaConfig, public/assets/$(name).json)
|
||||||
ICON = public/assets/icon32.png public/assets/icon256.png public/favicon.ico
|
ICON = public/assets/icon32.png public/assets/icon256.png public/favicon.ico
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
"levelFilename": "puzzle<n>.json",
|
"levelFilename": "puzzle<n>.json",
|
||||||
"levelDisplay": "Level <n>",
|
"levelDisplay": "Level <n>",
|
||||||
"levels": [
|
"levels": [
|
||||||
1, 2
|
1, 2, 3
|
||||||
],
|
],
|
||||||
"nextLevel": true
|
"nextLevel": true
|
||||||
}
|
}
|
||||||
|
|
BIN
assets/spikes.png
Executable file
BIN
assets/spikes.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
assets/switch.png
Executable file
BIN
assets/switch.png
Executable file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
22
levels/puzzle3.json
Normal file
22
levels/puzzle3.json
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"world": [
|
||||||
|
"A i B",
|
||||||
|
" i s",
|
||||||
|
" Cik ",
|
||||||
|
"SSSSSSSSSSSiiiii",
|
||||||
|
" i f",
|
||||||
|
" i ",
|
||||||
|
" s itttt",
|
||||||
|
" t wKKKK",
|
||||||
|
" w ",
|
||||||
|
" wD "
|
||||||
|
],
|
||||||
|
"snake": [
|
||||||
|
[0, 9],
|
||||||
|
[1, 9],
|
||||||
|
[2, 9]
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"moveCount": 60
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,6 +14,8 @@ const assetSpecs=[
|
||||||
{ name: 'portalD', filename: 'portal-d-anim.png', type: 'image' },
|
{ name: 'portalD', filename: 'portal-d-anim.png', type: 'image' },
|
||||||
{ name: 'key', filename: 'key32.png', type: 'image' },
|
{ name: 'key', filename: 'key32.png', type: 'image' },
|
||||||
{ name: 'door', filename: 'door32.png', type: 'image' },
|
{ name: 'door', filename: 'door32.png', type: 'image' },
|
||||||
|
{ name: 'switch', filename: 'switch-ts.png', type: 'image' },
|
||||||
|
{ name: 'spikes', filename: 'spikes-ts.png', type: 'image' },
|
||||||
{ name: 'snake', filename: 'snake.json', type: 'json' },
|
{ name: 'snake', filename: 'snake.json', type: 'json' },
|
||||||
{ name: 'levelList', filename: 'levelList.json', type: 'json' },
|
{ name: 'levelList', filename: 'levelList.json', type: 'json' },
|
||||||
{ name: 'config', filename: 'config.json', type: 'json' },
|
{ name: 'config', filename: 'config.json', type: 'json' },
|
||||||
|
@ -28,7 +30,9 @@ const tasks=[
|
||||||
{ from: 'portalC', type: 'animation', steps: 3 },
|
{ from: 'portalC', type: 'animation', steps: 3 },
|
||||||
{ from: 'portalD', type: 'animation', steps: 3 },
|
{ from: 'portalD', type: 'animation', steps: 3 },
|
||||||
{ from: 'superFruit', type: 'animation', steps: 5 },
|
{ from: 'superFruit', type: 'animation', steps: 5 },
|
||||||
{ from: 'decayFruit', type: 'animation', steps: 5 }
|
{ from: 'decayFruit', type: 'animation', steps: 5 },
|
||||||
|
{ from: 'switch', type: 'tileset', steps: 1, tiles: ['on', 'off'] },
|
||||||
|
{ from: 'spikes', type: 'tileset', steps: 1, tiles: ['off', 'on'] }
|
||||||
];
|
];
|
||||||
|
|
||||||
const cvs=document.createElement('canvas');
|
const cvs=document.createElement('canvas');
|
||||||
|
|
|
@ -1,4 +1,13 @@
|
||||||
const [EMPTY, FOOD, SUPER_FOOD, DECAY_FOOD, WALL, FIRE, FLAMMABLE, FLAMMABLE_S, HOLE, HOLE_S, PORTAL_A, PORTAL_A_S, PORTAL_B, PORTAL_B_S, PORTAL_C, PORTAL_C_S, PORTAL_D, PORTAL_D_S, KEY, DOOR, SNAKE]=Array(255).keys();
|
const [
|
||||||
|
EMPTY, SNAKE,
|
||||||
|
FOOD, SUPER_FOOD, DECAY_FOOD,
|
||||||
|
WALL,
|
||||||
|
FIRE, FLAMMABLE, FLAMMABLE_S,
|
||||||
|
HOLE, HOLE_S,
|
||||||
|
PORTAL_A, PORTAL_A_S, PORTAL_B, PORTAL_B_S, PORTAL_C, PORTAL_C_S, PORTAL_D, PORTAL_D_S,
|
||||||
|
KEY, DOOR,
|
||||||
|
SWITCH_ON, SWITCH_ON_S, SWITCH_OFF, SWITCH_OFF_S, SPIKES_OFF, SPIKES_OFF_S, SPIKES_ON
|
||||||
|
]=Array(255).keys();
|
||||||
|
|
||||||
class SnekGame {
|
class SnekGame {
|
||||||
constructor(settings, canvas, rules) {
|
constructor(settings, canvas, rules) {
|
||||||
|
@ -32,6 +41,9 @@ class SnekGame {
|
||||||
case 'D': return PORTAL_D;
|
case 'D': return PORTAL_D;
|
||||||
case 'k': return KEY;
|
case 'k': return KEY;
|
||||||
case 'K': return DOOR;
|
case 'K': return DOOR;
|
||||||
|
case 's': return SWITCH_OFF;
|
||||||
|
case 'S': return SPIKES_ON;
|
||||||
|
case 't': return SPIKES_OFF;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
}
|
}
|
||||||
|
@ -109,6 +121,13 @@ class SnekGame {
|
||||||
|
|
||||||
// add the doors
|
// add the doors
|
||||||
if(settings.doors) settings.doors.forEach(([x, y]) => this.world[x][y]=DOOR);
|
if(settings.doors) settings.doors.forEach(([x, y]) => this.world[x][y]=DOOR);
|
||||||
|
|
||||||
|
// add the switches
|
||||||
|
if(settings.switches) settings.switches.forEach(([x, y]) => this.world[x][y]=SWITCH_OFF);
|
||||||
|
|
||||||
|
// add the spikes
|
||||||
|
if(settings.spikesOn) settings.spikesOn.forEach(([x, y]) => this.world[x][y]=SPIKES_ON);
|
||||||
|
if(settings.spikesOff) settings.spikesOff.forEach(([x, y]) => this.world[x][y]=SPIKES_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the snake to the world
|
// add the snake to the world
|
||||||
|
@ -235,6 +254,8 @@ class SnekGame {
|
||||||
const portalD=assets.get('portalD');
|
const portalD=assets.get('portalD');
|
||||||
const key=assets.get('key');
|
const key=assets.get('key');
|
||||||
const door=assets.get('door');
|
const door=assets.get('door');
|
||||||
|
const switchTile=assets.get('switch');
|
||||||
|
const spikes=assets.get('spikes');
|
||||||
const putTile=(x, y, tile) => this.ctx.drawImage(
|
const putTile=(x, y, tile) => this.ctx.drawImage(
|
||||||
tile,
|
tile,
|
||||||
offsetX+cellSize*x,
|
offsetX+cellSize*x,
|
||||||
|
@ -316,6 +337,23 @@ class SnekGame {
|
||||||
case DOOR:
|
case DOOR:
|
||||||
putTile(x, y, door);
|
putTile(x, y, door);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SWITCH_ON:
|
||||||
|
case SWITCH_ON_S:
|
||||||
|
putTile(x, y, switchTile.on);
|
||||||
|
break;
|
||||||
|
case SWITCH_OFF:
|
||||||
|
case SWITCH_OFF_S:
|
||||||
|
putTile(x, y, switchTile.off);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPIKES_ON:
|
||||||
|
putTile(x, y, spikes.on);
|
||||||
|
break;
|
||||||
|
case SPIKES_OFF:
|
||||||
|
case SPIKES_OFF_S:
|
||||||
|
putTile(x, y, spikes.off);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -511,6 +549,15 @@ class SnekGame {
|
||||||
case PORTAL_D_S:
|
case PORTAL_D_S:
|
||||||
this.world[tail[0]][tail[1]]=PORTAL_D;
|
this.world[tail[0]][tail[1]]=PORTAL_D;
|
||||||
break;
|
break;
|
||||||
|
case SWITCH_ON_S:
|
||||||
|
this.world[tail[0]][tail[1]]=SWITCH_ON;
|
||||||
|
break;
|
||||||
|
case SWITCH_OFF_S:
|
||||||
|
this.world[tail[0]][tail[1]]=SWITCH_OFF;
|
||||||
|
break;
|
||||||
|
case SPIKES_OFF_S:
|
||||||
|
this.world[tail[0]][tail[1]]=SPIKES_OFF;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this.world[tail[0]][tail[1]]=EMPTY;
|
this.world[tail[0]][tail[1]]=EMPTY;
|
||||||
}
|
}
|
||||||
|
@ -530,6 +577,7 @@ class SnekGame {
|
||||||
case WALL: return this.die("thought walls were edible", "hit a wall");
|
case WALL: return this.die("thought walls were edible", "hit a wall");
|
||||||
case FIRE: return this.die("burned to a crisp", "hit fire");
|
case FIRE: return this.die("burned to a crisp", "hit fire");
|
||||||
case DOOR: return this.die("forgot to OPEN the door", "hit a door");
|
case DOOR: return this.die("forgot to OPEN the door", "hit a door");
|
||||||
|
case SPIKES_ON: return this.die("thought they were a girl's drink in a nightclub", "hit spikes");
|
||||||
|
|
||||||
// congratilations, you played yourself!
|
// congratilations, you played yourself!
|
||||||
case SNAKE:
|
case SNAKE:
|
||||||
|
@ -539,6 +587,9 @@ class SnekGame {
|
||||||
case PORTAL_B_S:
|
case PORTAL_B_S:
|
||||||
case PORTAL_C_S:
|
case PORTAL_C_S:
|
||||||
case PORTAL_D_S:
|
case PORTAL_D_S:
|
||||||
|
case SWITCH_OFF_S:
|
||||||
|
case SWITCH_ON_S:
|
||||||
|
case SPIKES_OFF_S:
|
||||||
return this.die("achieved every dog's dream", "ate their own tail");
|
return this.die("achieved every dog's dream", "ate their own tail");
|
||||||
|
|
||||||
// if either 3 consecutive segments or the whole snake is on a hole, you die
|
// if either 3 consecutive segments or the whole snake is on a hole, you die
|
||||||
|
@ -571,6 +622,16 @@ class SnekGame {
|
||||||
this.getTilesOfType(DOOR).forEach(([x, y]) => this.world[x][y]=EMPTY);
|
this.getTilesOfType(DOOR).forEach(([x, y]) => this.world[x][y]=EMPTY);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// you step on, you trigger
|
||||||
|
case SWITCH_ON:
|
||||||
|
case SWITCH_OFF: {
|
||||||
|
this.world[head[0]][head[1]]=this.world[head[0]][head[1]]==SWITCH_ON?SWITCH_OFF:SWITCH_ON;
|
||||||
|
if(this.getTilesOfType(SPIKES_OFF_S).length) return this.die("spiked themselves", "activated spikes");
|
||||||
|
const oldSpikes=this.getTilesOfType(SPIKES_ON);
|
||||||
|
this.getTilesOfType(SPIKES_OFF).forEach(([x, y]) => this.world[x][y]=SPIKES_ON);
|
||||||
|
oldSpikes.forEach(([x, y]) => this.world[x][y]=SPIKES_OFF);
|
||||||
|
} break;
|
||||||
|
|
||||||
// you eat, you grow
|
// you eat, you grow
|
||||||
case FOOD:
|
case FOOD:
|
||||||
// re-grow the snake partially (can't hit the tail, but it's there for all other intents and purposes
|
// re-grow the snake partially (can't hit the tail, but it's there for all other intents and purposes
|
||||||
|
@ -638,6 +699,15 @@ class SnekGame {
|
||||||
case PORTAL_D:
|
case PORTAL_D:
|
||||||
this.world[head[0]][head[1]]=PORTAL_D_S;
|
this.world[head[0]][head[1]]=PORTAL_D_S;
|
||||||
break;
|
break;
|
||||||
|
case SWITCH_ON:
|
||||||
|
this.world[head[0]][head[1]]=SWITCH_ON_S;
|
||||||
|
break;
|
||||||
|
case SWITCH_OFF:
|
||||||
|
this.world[head[0]][head[1]]=SWITCH_OFF_S;
|
||||||
|
break;
|
||||||
|
case SPIKES_OFF:
|
||||||
|
this.world[head[0]][head[1]]=SPIKES_OFF_S;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
this.world[head[0]][head[1]]=SNAKE;
|
this.world[head[0]][head[1]]=SNAKE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue