diff options
Diffstat (limited to 'src/systems')
-rw-r--r-- | src/systems/collision.js | 2 | ||||
-rw-r--r-- | src/systems/grid.js | 4 | ||||
-rw-r--r-- | src/systems/logic.js | 110 | ||||
-rw-r--r-- | src/systems/menu.js | 30 | ||||
-rw-r--r-- | src/systems/particle.js | 2 | ||||
-rw-r--r-- | src/systems/physics.js | 4 | ||||
-rw-r--r-- | src/systems/render.js | 4 | ||||
-rw-r--r-- | src/systems/undo.js | 10 |
8 files changed, 139 insertions, 27 deletions
diff --git a/src/systems/collision.js b/src/systems/collision.js index 0070ee7..d769636 100644 --- a/src/systems/collision.js +++ b/src/systems/collision.js @@ -44,7 +44,7 @@ game.system.Collision = (entitiesGrid) => { 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})) + e.addComponent(game.components.Momentum({...momentum})); }); } } diff --git a/src/systems/grid.js b/src/systems/grid.js index 6add388..6d4cf84 100644 --- a/src/systems/grid.js +++ b/src/systems/grid.js @@ -32,7 +32,7 @@ game.system.Grid = (entitiesGrid) => { const { x, y } = entity.components.gridPosition; entitiesGrid[y][x].set(entity.id, entity); }); - } + }; const update = (_elapsedTime, entities, changedIds) => { gridEntities = Object.keys(entities).filter((x) => entities[x].hasComponent("gridPosition")).map((x) => entities[x]); @@ -68,4 +68,4 @@ game.system.Grid = (entitiesGrid) => { return { gameCoordsToGrid, gridCoordsToGame, update, gridWidth, gridHeight }; -};
\ No newline at end of file +}; diff --git a/src/systems/logic.js b/src/systems/logic.js new file mode 100644 index 0000000..8e3bbc0 --- /dev/null +++ b/src/systems/logic.js @@ -0,0 +1,110 @@ +game.system.Logic = (entitiesGrid) => { + "use strict"; + let currentVerbRules = []; + const isWord = (entity) => entity.hasComponent("gridPosition") && (entity.hasComponent("verb") || entity.hasComponent("noun")); + + const getFirstWordEntity = (gridPosition) => { + if (!equivalence(gridPosition, clamp(gridPosition, game.config.xDim, game.config.yDim))) { + return null; + } + for (let entity of entitiesGrid[gridPosition.y][gridPosition.x].values()) { + if (isWord(entity)) { + return entity; + } + } + return null; + }; + + const verbActionsToComponent = { + "stop": game.components.Stop(), + "push": game.components.Pushable(), + "you": game.components.Controllable({controls: ['left', 'right', 'up', 'down']}), + + }; + + const nounsToEntityCreators = { + "rock": game.createRock, + "wall": game.createWall, + }; + + const doOnRule = (rule, entities, direction) => { + const [applyee, application] = [entities[rule[0]], entities[rule[1]]]; + const changedEntityIds = []; + if (applyee.hasComponent("noun")) { + const entityName = applyee.components.noun.select; + if (application.hasComponent("verb")) { + const verb = application.components.verb.action; + if (direction == "apply") { + currentVerbRules.push(rule); + } + for (let id in entities) { + if (entities[id].hasComponent("name") && entities[id].components.name.selector == entityName) { + changedEntityIds.push(id); + const component = verbActionsToComponent[verb]; + if (component) { + if (direction == "apply") { + entities[id].addComponent(component); + } else if (direction == "deapply") { + entities[id].removeComponent(component.name); + } + } + } + } + } + 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 e = nounsToEntityCreators[applicationEntityName](); + entities[id].components.name = e.components.name; + entities[id].components.sprite = e.components.sprite; + } + } + } + }; + return changedEntityIds; + }; + + const parseRules = (entities) => { + currentVerbRules.map((rule) => doOnRule(rule, entities, "deapply")); + currentVerbRules = []; + const isWordGridPositions = []; + const changedEntityIds = new Set(); + entitiesGrid.forEach((row) => row.forEach((entitiesInCell) => { + for (let entity of entitiesInCell.values()) { + if (isWord(entity) && entity.hasComponent("verb") && entity.components.verb.action == "Is") { + isWordGridPositions.push(entity.components.gridPosition); + } + } + })); + let newRules = []; + isWordGridPositions.forEach((gridPosition) => { + const east = getFirstWordEntity({y: gridPosition.y, x: gridPosition.x - 1}); + const west = getFirstWordEntity({y: gridPosition.y, x: gridPosition.x + 1}); + const north = getFirstWordEntity({x: gridPosition.x, y: gridPosition.y - 1}); + const south = getFirstWordEntity({x: gridPosition.x, y: gridPosition.y + 1}); + + if (east && west) { + newRules.push([east.id, west.id]); + } + if (north && south) { + newRules.push([north.id, south.id]); + } + }); + newRules = newRules.sort((a, b) => (entities[b[1]].hasComponent("noun") ? 1 : -1) - (entities[a[1]].hasComponent("noun") ? 1 : -1)); + newRules.map((rule) => doOnRule(rule, entities, "apply").map((id) => changedEntityIds.add(id))); + return changedEntityIds; + }; + + const update = (_elapsedTime, entities, changedIds) => { + for (let id of changedIds) { + const changed = entities[id]; + if (changed.hasComponent("verb") || changed.hasComponent("noun")) { + return parseRules(entities); + } + } + return new Set(); + }; + + return { update, parseRules }; +}; diff --git a/src/systems/menu.js b/src/systems/menu.js index 17153d0..629a6a3 100644 --- a/src/systems/menu.js +++ b/src/systems/menu.js @@ -7,23 +7,23 @@ game.system.Menu = () => { if (e.key == "Escape") { setState('main'); } - } + }; const setState = (newState) => { state = newState; draw(); - } + }; const bringUpMenu = () => { game.running = false; window.addEventListener("keydown", escapeEventListener); setState("main"); - } + }; const hide = () => { menuElement.style.display = "none"; game.startLoop(); - } + }; const listenFor = (action, elementId) => { const element = document.getElementById(elementId); @@ -37,14 +37,14 @@ game.system.Menu = () => { game.controls[action] = event.key; localStorage.setItem("controls", JSON.stringify(game.controls)); element.innerHTML = event.key; - } + }; window.addEventListener("keydown", handleKey); - } + }; const setLevel = (index) => { game.loadLevelIndex(index); hide(); - } + }; const draw = () => { menuElement.style.display = "block"; @@ -73,7 +73,7 @@ game.system.Menu = () => { Reset: <button id="reset" onfocus='game.systems.menu.listenFor("reset", "reset")'>${game.controls.reset}</button> </p> </div> - ` + `; } else if (state == "credits") { menuElement.innerHTML += ` <div> @@ -85,23 +85,23 @@ game.system.Menu = () => { Developed by Logan Hunt, Ethan Payne </p> </div> - ` + `; } else if (state == "levelSelect") { menuElement.innerHTML += ` <div> <p> Select a level to play: </p> ${ game.levels.map((level, index) => { - return `<div class='menu-button' onclick='game.systems.menu.setLevel(${index});'>${level.levelName}</div>` + return `<div class='menu-button' onclick='game.systems.menu.setLevel(${index});'>${level.levelName}</div>`; }).join("") } `; } - menuElement.innerHTML += "<div class='menu-button' onclick='game.systems.menu.hide()'>Resume Game</div>" + menuElement.innerHTML += "<div class='menu-button' onclick='game.systems.menu.hide()'>Resume Game</div>"; if (state !== "main") { - menuElement.innerHTML += "<div class='menu-button' onclick='game.systems.menu.setState(\"main\")'>Back</div>" + menuElement.innerHTML += "<div class='menu-button' onclick='game.systems.menu.setState(\"main\")'>Back</div>"; } - } - + }; + return { bringUpMenu, setState, listenFor, hide, setLevel, state }; -}
\ No newline at end of file +}; diff --git a/src/systems/particle.js b/src/systems/particle.js index e58c0a0..56d8c47 100644 --- a/src/systems/particle.js +++ b/src/systems/particle.js @@ -19,7 +19,7 @@ game.system.Particle = () => { } return particleSpec; }); - } + }; const update = (elapsedTime, entities, _changedIds) => { for (let id in entities) { diff --git a/src/systems/physics.js b/src/systems/physics.js index d72b1a0..18c3cb3 100644 --- a/src/systems/physics.js +++ b/src/systems/physics.js @@ -11,6 +11,6 @@ game.system.Physics = () => { } return new Set(); - } + }; return { update }; -}
\ No newline at end of file +}; diff --git a/src/systems/render.js b/src/systems/render.js index adc8355..8a3e633 100644 --- a/src/systems/render.js +++ b/src/systems/render.js @@ -10,7 +10,7 @@ game.system.Render = (graphics) => { }); sortedEntities.forEach((entity) => { - if (entity.hasComponent("position") && entity.hasComponent("appearance")) { + if (entity.hasComponent("position") && entity.hasComponent("appearance") && entity.hasComponent("alive")) { const drawSpec = {...entity.components.position, ...entity.components.appearance}; if (entity.hasComponent("sprite")) { game.sprites[entity.components.sprite.spriteName].draw(elapsedTime, drawSpec); @@ -21,6 +21,6 @@ game.system.Render = (graphics) => { }); return new Set(); - } + }; return { update }; }; diff --git a/src/systems/undo.js b/src/systems/undo.js index 29f5bec..086d6b4 100644 --- a/src/systems/undo.js +++ b/src/systems/undo.js @@ -1,4 +1,4 @@ -game.system.Undo = (entitiesGrid) => { +game.system.Undo = (entitiesGrid, logicSystem, gridSystem) => { const states = []; const update = (elapsedTime, entities, changedIds) => { @@ -12,7 +12,7 @@ game.system.Undo = (entitiesGrid) => { states.push(state); } return new Set(); - } + }; const undo = (entities) => { let state = states.slice(0, -1).pop(); @@ -24,7 +24,9 @@ game.system.Undo = (entitiesGrid) => { entities[id].addComponent({name: componentName, ...state[id][componentName]}); } } - } + gridSystem.update(0, entities, new Set()); + logicSystem.parseRules(entities); + }; return { update, undo }; -}
\ No newline at end of file +}; |