summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Hunt <loganhunt@simponic.xyz>2022-04-19 16:02:53 -0600
committerLogan Hunt <loganhunt@simponic.xyz>2022-04-19 16:02:53 -0600
commit58ceff79496f60969eecb28a767b1ea28292becb (patch)
tree3a6acad4d9333aef2e18bb5d073e054926b20340
parent9b597426ac45775f63b1fe4365c6fa8f3c3179af (diff)
downloadbbiy-58ceff79496f60969eecb28a767b1ea28292becb.tar.gz
bbiy-58ceff79496f60969eecb28a767b1ea28292becb.zip
Finish rule system; add burn and sink; particle effects on kill, sink
-rw-r--r--src/bootstrap.js4
-rw-r--r--src/components/burn.js1
-rw-r--r--src/components/burnable.js1
-rw-r--r--src/components/sink.js1
-rw-r--r--src/components/sinkable.js1
-rw-r--r--src/components/win.js1
-rw-r--r--src/entities/bigblue.js3
-rw-r--r--src/entities/borderParticles.js5
-rw-r--r--src/entities/flag.js1
-rw-r--r--src/entities/lava.js2
-rw-r--r--src/entities/rock.js1
-rw-r--r--src/entities/water.js1
-rw-r--r--src/entities/wordFlag.js3
-rw-r--r--src/entities/wordKill.js1
-rw-r--r--src/entities/wordLava.js1
-rw-r--r--src/entities/wordSink.js3
-rw-r--r--src/entities/wordWater.js3
-rw-r--r--src/entities/wordWin.js3
-rw-r--r--src/systems/collision.js107
-rw-r--r--src/systems/keyboardInput.js2
-rw-r--r--src/systems/logic.js35
-rw-r--r--src/systems/render.js2
22 files changed, 127 insertions, 55 deletions
diff --git a/src/bootstrap.js b/src/bootstrap.js
index c15bf53..4519ed2 100644
--- a/src/bootstrap.js
+++ b/src/bootstrap.js
@@ -18,7 +18,9 @@ game.bootstrap = (() => {
'src/components/appearence.js', 'src/components/controllable.js', 'src/components/pushable.js',
'src/components/loadPriority.js', 'src/components/stop.js', 'src/components/alive.js',
'src/components/sprite.js', 'src/components/particles.js', 'src/components/noun.js',
- 'src/components/name.js', 'src/components/verb.js',
+ 'src/components/name.js', 'src/components/verb.js', 'src/components/burn.js',
+ 'src/components/burnable.js', 'src/components/sink.js', 'src/components/sinkable.js',
+ 'src/components/win.js',
],
id: 'components'
},
diff --git a/src/components/burn.js b/src/components/burn.js
new file mode 100644
index 0000000..f138e9d
--- /dev/null
+++ b/src/components/burn.js
@@ -0,0 +1 @@
+game.components.Burn = () => game.Component('burn', {}); \ No newline at end of file
diff --git a/src/components/burnable.js b/src/components/burnable.js
new file mode 100644
index 0000000..d5767e7
--- /dev/null
+++ b/src/components/burnable.js
@@ -0,0 +1 @@
+game.components.Burnable = () => game.Component('burnable', {}); \ No newline at end of file
diff --git a/src/components/sink.js b/src/components/sink.js
new file mode 100644
index 0000000..3a4d9dc
--- /dev/null
+++ b/src/components/sink.js
@@ -0,0 +1 @@
+game.components.Sink = () => game.Component('sink', {}); \ No newline at end of file
diff --git a/src/components/sinkable.js b/src/components/sinkable.js
new file mode 100644
index 0000000..1fcb132
--- /dev/null
+++ b/src/components/sinkable.js
@@ -0,0 +1 @@
+game.components.Sinkable = () => game.Component('sinkable', {}); \ No newline at end of file
diff --git a/src/components/win.js b/src/components/win.js
new file mode 100644
index 0000000..ea905fc
--- /dev/null
+++ b/src/components/win.js
@@ -0,0 +1 @@
+game.components.Win = () => game.Component('win', {}); \ No newline at end of file
diff --git a/src/entities/bigblue.js b/src/entities/bigblue.js
index bcf80d5..45fbc90 100644
--- a/src/entities/bigblue.js
+++ b/src/entities/bigblue.js
@@ -4,9 +4,10 @@ game.createBigBlue = () => {
bigBlue.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
bigBlue.addComponent(game.components.Alive());
bigBlue.addComponent(game.components.Sprite({spriteName: "bigBlue"}));
-
// bigBlue.addComponent(game.components.Controllable({controls: ['left', 'right', 'up', 'down']}));
bigBlue.addComponent(game.components.Name({selector: "bigblue"}));
+ bigBlue.addComponent(game.components.Burnable());
+ bigBlue.addComponent(game.components.Sinkable());
return bigBlue;
};
diff --git a/src/entities/borderParticles.js b/src/entities/borderParticles.js
index 260071d..e1a7e98 100644
--- a/src/entities/borderParticles.js
+++ b/src/entities/borderParticles.js
@@ -1,4 +1,4 @@
-game.createBorderParticles = () => {
+game.createBorderParticles = (spawnerSpec) => {
const particleSpawner = game.Entity();
const spawnFunction = (particleSpec) => {
switch (Math.floor(Math.random() * 4)) {
@@ -24,7 +24,7 @@ game.createBorderParticles = () => {
particleSpawner.addComponent(game.components.Particles({
spec: {
spawnFunction,
- colors: ["#16f7c9", "#0d6e5a", "#2fa18a", "#48cfb4", "#58877d", "#178054", "#2cdb92"],
+ colors: ["#666666", "#777777", "#888888", "#999999"],
maxSpeed: 0.20,
minRadius: 1,
maxRadius: 3,
@@ -32,6 +32,7 @@ game.createBorderParticles = () => {
maxLife: 300,
minAmount: 20,
maxAmount: 50,
+ ...spawnerSpec,
}
}));
particleSpawner.addComponent(game.components.LoadPriority({priority: 1}));
diff --git a/src/entities/flag.js b/src/entities/flag.js
index e13d2a2..831922f 100644
--- a/src/entities/flag.js
+++ b/src/entities/flag.js
@@ -4,5 +4,6 @@ game.createFlag = () => {
flag.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
flag.addComponent(game.components.Alive());
flag.addComponent(game.components.Sprite({spriteName: "flag"}))
+ flag.addComponent(game.components.Name({selector: "flag"}));
return flag;
}
diff --git a/src/entities/lava.js b/src/entities/lava.js
index 4a88f69..e529812 100644
--- a/src/entities/lava.js
+++ b/src/entities/lava.js
@@ -4,6 +4,6 @@ game.createLava = () => {
lava.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
lava.addComponent(game.components.Alive());
lava.addComponent(game.components.Sprite({spriteName: "lava"}))
-
+ lava.addComponent(game.components.Name({selector: "lava"}));
return lava;
}
diff --git a/src/entities/rock.js b/src/entities/rock.js
index 6a28f6e..a87710a 100644
--- a/src/entities/rock.js
+++ b/src/entities/rock.js
@@ -8,6 +8,7 @@ game.createRock = () => {
// rock.addComponent(game.components.Pushable());
rock.addComponent(game.components.Name({selector: "rock"}));
+ rock.addComponent(game.components.Sinkable());
return rock;
};
diff --git a/src/entities/water.js b/src/entities/water.js
index 7c160b0..11522b1 100644
--- a/src/entities/water.js
+++ b/src/entities/water.js
@@ -4,5 +4,6 @@ game.createWater = () => {
water.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
water.addComponent(game.components.Alive());
water.addComponent(game.components.Sprite({spriteName: "water"}))
+ water.addComponent(game.components.Name({selector: "water"}))
return water;
}
diff --git a/src/entities/wordFlag.js b/src/entities/wordFlag.js
index bc2d782..79617ea 100644
--- a/src/entities/wordFlag.js
+++ b/src/entities/wordFlag.js
@@ -4,6 +4,7 @@ game.createWordFlag = () => {
wordFlag.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordFlag.addComponent(game.components.Pushable({pushable: true}));
wordFlag.addComponent(game.components.Alive());
- wordFlag.addComponent(game.components.Sprite({spriteName: "wordFlag"}))
+ wordFlag.addComponent(game.components.Sprite({spriteName: "wordFlag"}));
+ wordFlag.addComponent(game.components.Noun({select: "flag"}));
return wordFlag;
}
diff --git a/src/entities/wordKill.js b/src/entities/wordKill.js
index 8ea04d9..6906e9c 100644
--- a/src/entities/wordKill.js
+++ b/src/entities/wordKill.js
@@ -5,5 +5,6 @@ game.createWordKill = () => {
wordKill.addComponent(game.components.Pushable({pushable: true}));
wordKill.addComponent(game.components.Alive());
wordKill.addComponent(game.components.Sprite({spriteName: "wordKill"}))
+ wordKill.addComponent(game.components.Verb({action: "burn"}));
return wordKill;
}
diff --git a/src/entities/wordLava.js b/src/entities/wordLava.js
index bb7a005..cf31286 100644
--- a/src/entities/wordLava.js
+++ b/src/entities/wordLava.js
@@ -6,5 +6,6 @@ game.createWordLava = () => {
wordLava.addComponent(game.components.Alive());
wordLava.addComponent(game.components.Sprite({spriteName: "wordLava"}))
+ wordLava.addComponent(game.components.Noun({select: "lava"}));
return wordLava;
}
diff --git a/src/entities/wordSink.js b/src/entities/wordSink.js
index decd480..369f922 100644
--- a/src/entities/wordSink.js
+++ b/src/entities/wordSink.js
@@ -4,6 +4,7 @@ game.createWordSink = () => {
wordSink.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordSink.addComponent(game.components.Pushable({pushable: true}));
wordSink.addComponent(game.components.Alive());
- wordSink.addComponent(game.components.Sprite({spriteName: "wordSink"}))
+ wordSink.addComponent(game.components.Sprite({spriteName: "wordSink"}));
+ wordSink.addComponent(game.components.Verb({action: "sink"}));
return wordSink;
}
diff --git a/src/entities/wordWater.js b/src/entities/wordWater.js
index c6404bf..eb0c1be 100644
--- a/src/entities/wordWater.js
+++ b/src/entities/wordWater.js
@@ -4,6 +4,7 @@ game.createWordWater = () => {
wordWater.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordWater.addComponent(game.components.Pushable({pushable: true}));
wordWater.addComponent(game.components.Alive());
- wordWater.addComponent(game.components.Sprite({spriteName: "wordWater"}))
+ wordWater.addComponent(game.components.Sprite({spriteName: "wordWater"}));
+ wordWater.addComponent(game.components.Noun({select: "water"}));
return wordWater;
}
diff --git a/src/entities/wordWin.js b/src/entities/wordWin.js
index ed837d0..e8948ee 100644
--- a/src/entities/wordWin.js
+++ b/src/entities/wordWin.js
@@ -4,6 +4,7 @@ game.createWordWin = () => {
wordWin.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordWin.addComponent(game.components.Pushable({pushable: true}));
wordWin.addComponent(game.components.Alive());
- wordWin.addComponent(game.components.Sprite({spriteName: "wordWin"}))
+ wordWin.addComponent(game.components.Sprite({spriteName: "wordWin"}));
+ wordWin.addComponent(game.components.Verb({action: "win"}));
return wordWin;
}
diff --git a/src/systems/collision.js b/src/systems/collision.js
index d769636..013ae1e 100644
--- a/src/systems/collision.js
+++ b/src/systems/collision.js
@@ -2,50 +2,83 @@ game.system.Collision = (entitiesGrid) => {
const update = (elapsedTime, entities, changedIds) => {
const thisChangedIds = new Set();
for (let entity of Object.keys(entities).map((id) => entities[id])) {
- if (entity.hasComponent("controllable") && entity.hasComponent("gridPosition") && entity.hasComponent("momentum")) {
- const momentum = unitize(entity.components.momentum);
-
- let found;
- const proposed = {x: entity.components.gridPosition.x + momentum.dx, y: entity.components.gridPosition.y + momentum.dy};
- const entitiesToPush = [];
- let wall = false;
- do {
- const proposedClampedInBounds = clamp(proposed, game.config.xDim-1, game.config.yDim-1);
- if (!equivalence(proposed, proposedClampedInBounds)) {
- break;
+ if (entity.hasComponent("position") && entity.hasComponent("gridPosition") && (entity.hasComponent("burnable") || entity.hasComponent("sinkable")) && entity.hasComponent("alive")) {
+ for (let collided of entitiesGrid[entity.components.gridPosition.y][entity.components.gridPosition.x].values()) {
+ if (!equivalence(entity, collided) && collided.hasComponent("alive")){
+ if (entity.hasComponent("burnable") && collided.hasComponent("burn")) {
+ const burnedParticleSpawner = game.createBorderParticles({colors: ["#f58d42", "#d6600b", "#c7a312", "#f2b844"]});
+ burnedParticleSpawner.addComponent(game.components.Position(collided.components.position));
+ burnedParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
+ game.entities[burnedParticleSpawner.id] = burnedParticleSpawner;
+ entity.removeComponent("alive");
+ break;
+ } else if (entity.hasComponent("sinkable") && collided.hasComponent("sink")) {
+ const sunkParticleSpawner = game.createBorderParticles({colors: ["#16f7c9", "#0d6e5a", "#2fa18a", "#48cfb4", "#58877d", "#178054", "#2cdb92"]});
+ sunkParticleSpawner.addComponent(game.components.Position(collided.components.position));
+ sunkParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
+ game.entities[sunkParticleSpawner.id] = sunkParticleSpawner;
+ entity.removeComponent("alive");
+ collided.removeComponent("alive");
+ break;
+ }
}
+ }
+ }
+ if (entity.hasComponent("controllable") && entity.hasComponent("gridPosition")) {
+ for (let collided of entitiesGrid[entity.components.gridPosition.y][entity.components.gridPosition.x].values()) {
+ if (collided.hasComponent("win")) {
+ game.systems.menu.bringUpMenu();
+ game.systems.menu.setState("levelSelect");
+ }
+ }
- found = false;
-
- const entitiesInCell = entitiesGrid[proposed.y][proposed.x];
+ if (entity.hasComponent("momentum")) {
+ const momentum = unitize(entity.components.momentum);
- for (let next of entitiesInCell.values()) {
- if (next.hasComponent("stop")) {
- wall = next;
- found = false;
+ let found;
+ const proposed = {x: entity.components.gridPosition.x + momentum.dx, y: entity.components.gridPosition.y + momentum.dy};
+ const entitiesToPush = [];
+ let wall = false;
+ do {
+ const proposedClampedInBounds = clamp(proposed, game.config.xDim-1, game.config.yDim-1);
+ if (!equivalence(proposed, proposedClampedInBounds)) {
break;
}
- if (next.hasComponent("pushable")) {
- entitiesToPush.push(next);
- found = true;
+
+ found = false;
+
+ const entitiesInCell = entitiesGrid[proposed.y][proposed.x];
+
+ for (let next of entitiesInCell.values()) {
+ if (next.hasComponent("alive")) {
+ if (next.hasComponent("stop")) {
+ wall = next;
+ found = false;
+ break;
+ }
+ if (next.hasComponent("pushable")) {
+ entitiesToPush.push(next);
+ found = true;
+ }
+ }
}
- }
- proposed.x += momentum.dx;
- proposed.y += momentum.dy;
- } while(found);
-
- if (wall) {
- entity.removeComponent("momentum");
- } else {
- entitiesToPush.map((e) => {
- const pushedParticleSpawner = game.createBorderParticles();
- pushedParticleSpawner.addComponent(game.components.Position(e.components.position));
- pushedParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
- game.entities[pushedParticleSpawner.id] = pushedParticleSpawner;
-
- e.addComponent(game.components.Momentum({...momentum}));
- });
+ proposed.x += momentum.dx;
+ proposed.y += momentum.dy;
+ } while(found);
+
+ if (wall) {
+ entity.removeComponent("momentum");
+ } else {
+ entitiesToPush.map((e) => {
+ const pushedParticleSpawner = game.createBorderParticles({maxSpeed: 0.1, minAmount: 10, maxAmount: 15});
+ pushedParticleSpawner.addComponent(game.components.Position(e.components.position));
+ pushedParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
+ game.entities[pushedParticleSpawner.id] = pushedParticleSpawner;
+
+ e.addComponent(game.components.Momentum({...momentum}));
+ });
+ }
}
}
}
diff --git a/src/systems/keyboardInput.js b/src/systems/keyboardInput.js
index 06a73c9..1b399ca 100644
--- a/src/systems/keyboardInput.js
+++ b/src/systems/keyboardInput.js
@@ -12,7 +12,7 @@ game.system.KeyboardInput = () => {
const update = (elapsedTime, entities, changedIds) => {
for (let id in entities) {
const entity = entities[id];
- if (entity.hasComponent('controllable')) {
+ if (entity.hasComponent('controllable') && entity.hasComponent('alive')) {
const controls = entity.components.controllable.controls;
if (!changedIds.has(entity.id)) {
if (controls.includes('left') && keys[game.controls.left]) {
diff --git a/src/systems/logic.js b/src/systems/logic.js
index 8e3bbc0..207fbc8 100644
--- a/src/systems/logic.js
+++ b/src/systems/logic.js
@@ -1,6 +1,7 @@
game.system.Logic = (entitiesGrid) => {
"use strict";
let currentVerbRules = [];
+ let previousControllableIds = new Set();
const isWord = (entity) => entity.hasComponent("gridPosition") && (entity.hasComponent("verb") || entity.hasComponent("noun"));
const getFirstWordEntity = (gridPosition) => {
@@ -19,12 +20,16 @@ game.system.Logic = (entitiesGrid) => {
"stop": game.components.Stop(),
"push": game.components.Pushable(),
"you": game.components.Controllable({controls: ['left', 'right', 'up', 'down']}),
-
+ "burn": game.components.Burn(),
+ "sink": game.components.Sink(),
+ "win": game.components.Win(),
};
const nounsToEntityCreators = {
"rock": game.createRock,
"wall": game.createWall,
+ "bigblue": game.createBigBlue,
+ "flag": game.createFlag,
};
const doOnRule = (rule, entities, direction) => {
@@ -38,26 +43,42 @@ game.system.Logic = (entitiesGrid) => {
currentVerbRules.push(rule);
}
for (let id in entities) {
- if (entities[id].hasComponent("name") && entities[id].components.name.selector == entityName) {
+ const entity = entities[id];
+ if (entity.hasComponent("alive") && entity.hasComponent("name") && entity.components.name.selector == entityName) {
changedEntityIds.push(id);
const component = verbActionsToComponent[verb];
if (component) {
if (direction == "apply") {
- entities[id].addComponent(component);
+ if (verb == "you") {
+ if (!previousControllableIds.has(id)) {
+ const newYouParticleSpawner = game.createBorderParticles({colors: ["#ffc0cb", "#ffb6c1", "#ffc1cc", "#ffbcd9", "#ff1493"], minAmount: 80, maxAmount: 150, maxSpeed: 0.5});
+ newYouParticleSpawner.addComponent(game.components.Position(entity.components.position));
+ newYouParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
+ game.entities[newYouParticleSpawner.id] = newYouParticleSpawner;
+ }
+ }
+ entity.addComponent(component);
} else if (direction == "deapply") {
- entities[id].removeComponent(component.name);
+ if (entity.hasComponent("controllable")) {
+ previousControllableIds.add(id);
+ }
+ entity.removeComponent(component.name);
}
}
}
}
+ if (direction == "apply" && changedEntityIds.some((id) => previousControllableIds.has(id))) {
+ previousControllableIds = new Set();
+ }
}
if (application.hasComponent("noun")) {
const applicationEntityName = application.components.noun.select;
for (let id in entities) {
- if (entities[id].hasComponent("name") && entities[id].components.name.selector == entityName) {
+ const entity = entities[id];
+ if (entity.hasComponent("name") && entity.components.name.selector == entityName) {
const e = nounsToEntityCreators[applicationEntityName]();
- entities[id].components.name = e.components.name;
- entities[id].components.sprite = e.components.sprite;
+ entity.components.name = e.components.name;
+ entity.components.sprite = e.components.sprite;
}
}
}
diff --git a/src/systems/render.js b/src/systems/render.js
index 8a3e633..e0db7e3 100644
--- a/src/systems/render.js
+++ b/src/systems/render.js
@@ -14,7 +14,7 @@ game.system.Render = (graphics) => {
const drawSpec = {...entity.components.position, ...entity.components.appearance};
if (entity.hasComponent("sprite")) {
game.sprites[entity.components.sprite.spriteName].draw(elapsedTime, drawSpec);
- } else if (entity.hasComponent("particles")) {
+ } else if (entity.hasComponent("particles") && entity.particleSprite) {
entity.particleSprite.draw(elapsedTime, drawSpec);
}
}