Wow this is some shitty fucking code god damn

This commit is contained in:
Logan Hunt 2022-04-18 21:07:55 -06:00
parent 1cffeb5520
commit 9b597426ac
27 changed files with 241 additions and 73 deletions

View File

@ -10,7 +10,7 @@ app.route('/').get((req, res) => {
});
app.route('/levels').get((req, res) => {
fs.readFile(path.join(__dirname, 'level-all.bbiy'), 'utf8', (err, data) => {
fs.readFile(path.join(__dirname, 'levels-all.bbiy'), 'utf8', (err, data) => {
if (err) {
console.log(err);
return;

View File

@ -1,3 +1,45 @@
(almost) No Rules
20 x 20
hhhhhhhhhhhhhhhhhhhh
h h
h h
h h
h h
h h
h h
h wwwwwwwwwwww h
h r h
h b r f h
h r h
h aaaaa vvvvv h
h h
h h
h h
h h
h h
h h
h h
hhhhhhhhhhhhhhhhhhhh
V IK A IN
W R
IS IP
BIY IX
F
Level-1
20 x 20
hhhhhhhhhhhhhhhhhhhh
@ -29,8 +71,8 @@ hhhhhhhhhhhhhhhhhhhh
wwwwwwwwwwww
r
r f
b r
b r f
r
wwwwwwwwwwww
BIY FIX
@ -67,8 +109,8 @@ hhhhhhhhhhhhhhhhhhhh
wwwwwwww
w I w
w w
w I w
wwwww X w
w w
w F f b w
@ -131,14 +173,14 @@ h h
h g h
h g gh
h h
h g h
h g h
h g g h
h h
h gg h
h h
h h
h h
h h
h h
h g h
h h
hg h
@ -160,7 +202,7 @@ hhhhhhhhhhhhhhhhhhhh
w w
w w
waaa w
waaa w
waaa FIX w
wfaa w
wwwwwwwwwwwwww
@ -203,7 +245,7 @@ hhhhhhhhhhhhhhhhhhhh
wBIYw r
F
I
RIP I
X
VIK

5
src/bootstrap.js vendored
View File

@ -17,7 +17,8 @@ game.bootstrap = (() => {
'src/components/position.js', 'src/components/momentum.js', 'src/components/gridPosition.js',
'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/sprite.js', 'src/components/particles.js', 'src/components/noun.js',
'src/components/name.js', 'src/components/verb.js',
],
id: 'components'
},
@ -37,7 +38,7 @@ game.bootstrap = (() => {
{
src: [
'src/systems/render.js', 'src/systems/grid.js', 'src/systems/physics.js', 'src/systems/keyboardInput.js',
'src/systems/collision.js', 'src/systems/undo.js', 'src/systems/particle.js', 'src/systems/menu.js'
'src/systems/collision.js', 'src/systems/undo.js', 'src/systems/particle.js', 'src/systems/menu.js', 'src/systems/logic.js',
],
id: 'systems' },
{ src: ['src/game.js'], id: 'game' },

View File

@ -4,5 +4,5 @@ game.Component = (name, spec) => {
return {
name,
...spec
}
};
};

1
src/components/name.js Normal file
View File

@ -0,0 +1 @@
game.components.Name = ({selector}) => game.Component('name', {selector});

1
src/components/noun.js Normal file
View File

@ -0,0 +1 @@
game.components.Noun = ({select}) => game.Component('noun', {select});

1
src/components/verb.js Normal file
View File

@ -0,0 +1 @@
game.components.Verb = ({action}) => game.Component('verb', {action});

View File

@ -3,10 +3,10 @@ game.createBigBlue = () => {
bigBlue.addComponent(game.components.LoadPriority({priority: 1}));
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.Sprite({spriteName: "bigBlue"}));
// TODO: Remove this
bigBlue.addComponent(game.components.Controllable({controls: ['left', 'right', 'up', 'down']}));
// bigBlue.addComponent(game.components.Controllable({controls: ['left', 'right', 'up', 'down']}));
bigBlue.addComponent(game.components.Name({selector: "bigblue"}));
return bigBlue;
}
};

View File

@ -3,10 +3,11 @@ game.createRock = () => {
rock.addComponent(game.components.LoadPriority({priority: 2}));
rock.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
rock.addComponent(game.components.Alive());
rock.addComponent(game.components.Sprite({spriteName: "rock"}))
rock.addComponent(game.components.Sprite({spriteName: "rock"}));;
//TODO: Remove this
rock.addComponent(game.components.Pushable());
// rock.addComponent(game.components.Pushable());
rock.addComponent(game.components.Name({selector: "rock"}));
return rock;
}
};

View File

@ -2,8 +2,9 @@ game.createWall = () => {
const wall = game.Entity();
wall.addComponent(game.components.LoadPriority({priority: 3}));
wall.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wall.addComponent(game.components.Stop());
// wall.addComponent(game.components.Stop());
wall.addComponent(game.components.Name({selector: "wall"}));
wall.addComponent(game.components.Alive());
wall.addComponent(game.components.Sprite({spriteName: "wall"}))
wall.addComponent(game.components.Sprite({spriteName: "wall"}));
return wall;
}
};

View File

@ -4,6 +4,7 @@ game.createWordBigBlue = () => {
wordBigBlue.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordBigBlue.addComponent(game.components.Pushable({pushable: true}));
wordBigBlue.addComponent(game.components.Alive());
wordBigBlue.addComponent(game.components.Sprite({spriteName: "wordBigBlue"}))
wordBigBlue.addComponent(game.components.Sprite({spriteName: "wordBigBlue"}));
wordBigBlue.addComponent(game.components.Noun({select: "bigblue"}));
return wordBigBlue;
}
};

View File

@ -5,6 +5,7 @@ game.createWordIs = () => {
// wordIs.addComponent(game.components.Stop({stop: true}));
wordIs.addComponent(game.components.Pushable());
wordIs.addComponent(game.components.Alive());
wordIs.addComponent(game.components.Sprite({spriteName: "wordIs"}))
wordIs.addComponent(game.components.Sprite({spriteName: "wordIs"}));
wordIs.addComponent(game.components.Verb({action: "Is"}));
return wordIs;
}
};

View File

@ -4,6 +4,7 @@ game.createWordPush = () => {
wordPush.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordPush.addComponent(game.components.Pushable({pushable: true}));
wordPush.addComponent(game.components.Alive());
wordPush.addComponent(game.components.Sprite({spriteName: "wordPush"}))
wordPush.addComponent(game.components.Sprite({spriteName: "wordPush"}));
wordPush.addComponent(game.components.Verb({action: "push"}));
return wordPush;
}
};

View File

@ -4,6 +4,7 @@ game.createWordRock = () => {
wordRock.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordRock.addComponent(game.components.Pushable({pushable: true}));
wordRock.addComponent(game.components.Alive());
wordRock.addComponent(game.components.Sprite({spriteName: "wordRock"}))
wordRock.addComponent(game.components.Sprite({spriteName: "wordRock"}));
wordRock.addComponent(game.components.Noun({select: "rock"}));
return wordRock;
}
};

View File

@ -4,6 +4,7 @@ game.createWordStop = () => {
wordStop.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordStop.addComponent(game.components.Pushable({pushable: true}));
wordStop.addComponent(game.components.Alive());
wordStop.addComponent(game.components.Sprite({spriteName: "wordStop"}))
wordStop.addComponent(game.components.Sprite({spriteName: "wordStop"}));
wordStop.addComponent(game.components.Verb({action: "stop"}));
return wordStop;
}
};

View File

@ -4,6 +4,7 @@ game.createWordWall = () => {
wordWall.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordWall.addComponent(game.components.Pushable({pushable: true}));
wordWall.addComponent(game.components.Alive());
wordWall.addComponent(game.components.Sprite({spriteName: "wordWall"}))
wordWall.addComponent(game.components.Noun({select: "wall"}));
wordWall.addComponent(game.components.Sprite({spriteName: "wordWall"}));
return wordWall;
}
};

View File

@ -4,6 +4,7 @@ game.createWordYou = () => {
wordYou.addComponent(game.components.Appearance({rot: 0, width: 100, height: 100}));
wordYou.addComponent(game.components.Pushable({pushable: true}));
wordYou.addComponent(game.components.Alive());
wordYou.addComponent(game.components.Sprite({spriteName: "wordYou"}))
wordYou.addComponent(game.components.Sprite({spriteName: "wordYou"}));
wordYou.addComponent(game.components.Verb({action: "you"}));
return wordYou;
}
};

View File

@ -14,36 +14,37 @@ game.loop = (timeStamp) => {
});
for (let id in game.entities) {
if (!game.entities[id].hasComponent("alive")) {
if (game.entities[id].hasComponent("particles") && !game.entities[id].hasComponent("alive")) {
delete game.entities[id];
}
}
requestAnimationFrame(game.loop);
}
};
game.toggleRunning = () => {
game.running = !game.running;
}
};
game.startLoop = () => {
game.running = true;
game.lastTimeStamp = performance.now();
requestAnimationFrame(game.loop);
}
};
game.loadSystems = () => {
game.systemOrder = ["grid", "collision", "physics", "keyboardInput", "undo", "particle", "render"];
game.systemOrder = ["grid", "collision", "physics", "keyboardInput", "particle", "logic", "undo", "render"];
game.systems = { };
game.systems.physics = game.system.Physics(),
game.systems.grid = game.system.Grid(game.entitiesGrid);
game.systems.collision = game.system.Collision(game.entitiesGrid);
game.systems.render = game.system.Render(game.graphics);
game.systems.undo = game.system.Undo(game.entitiesGrid);
game.systems.particle = game.system.Particle(game.canvas.context);
game.systems.keyboardInput = game.system.KeyboardInput();
game.systems.logic = game.system.Logic(game.entitiesGrid);
game.systems.undo = game.system.Undo(game.entitiesGrid, game.systems.logic, game.systems.grid);
game.systems.menu = game.system.Menu();
}
};
game.loadLevelIndex = (level) => {
game.level = level;
@ -52,9 +53,9 @@ game.loadLevelIndex = (level) => {
// Maintained by grid system as a side-effect
game.entitiesGrid = Array(game.config.yDim).fill(null).map(() => Array(game.config.xDim).fill(null).map(() => new Map()));
game.loadSystems();
}
};
game.initialize = () => {
game.loadLevelIndex(0);
game.startLoop();
}
};

View File

@ -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}));
});
}
}

View File

@ -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 };
};
};

110
src/systems/logic.js Normal file
View File

@ -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 };
};

View File

@ -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 };
}
};

View File

@ -19,7 +19,7 @@ game.system.Particle = () => {
}
return particleSpec;
});
}
};
const update = (elapsedTime, entities, _changedIds) => {
for (let id in entities) {

View File

@ -11,6 +11,6 @@ game.system.Physics = () => {
}
return new Set();
}
};
return { update };
}
};

View File

@ -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 };
};

View File

@ -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 };
}
};

View File

@ -3,4 +3,4 @@ const clamp = (vector, maxX, maxY) => {
newVector.x = Math.max(0, Math.min(maxX, vector.x));
newVector.y = Math.max(0, Math.min(maxY, vector.y));
return newVector;
}
};