diff --git a/static/engine.js b/static/engine.js
index ac1326c..24efc59 100644
--- a/static/engine.js
+++ b/static/engine.js
@@ -26,6 +26,7 @@ const engine = (() => {
let timer;
let time = Date.now();
let entities = {};
+ let components = {};
let events = {};
const engineTick = 1000 / 60;
@@ -45,37 +46,75 @@ const engine = (() => {
};
return (message, ...messageArgs) => {
switch (message) {
- case "queueEvent":
+ case "queueEvent": {
queue.push(messageArgs[0]);
break;
- case "events":
+ }
+ case "events": {
return events;
+ }
+ case "entities": {
+ return entities;
+ }
+ case "components": {
+ return components;
+ }
+ case "world": {
+ return {
+ entities,
+ components,
+ events,
+ };
+ }
+ case "registerEntity": {
+ let node = messageArgs[0];
+ entities[node] = [];
break;
- case "registerEntity":
+ }
+ case "removeEntity": {
+ let node = messageArgs[0];
+ entities[node].forEach(([componentType, component]) => {
+ components[componentType].remove(component);
+ });
+ delete entities[node];
+ queue.push((_) => node.remove());
break;
- case "removeEntity":
+ }
+ case "registerComponentType": {
+ let componentType = messageArgs[0];
+ components[componentType] = new Set();
break;
- case "registerEvent":
- {let eventName = messageArgs[0];
+ }
+ case "addComponent": {
+ let [entity, componentType, component] = messageArgs;
+ entities[entity].push([componentType, component]);
+ components[componentType].add(component);
+ break;
+ }
+ case "registerEvent": {
+ let eventName = messageArgs[0];
let newEvent = initEvent();
- events[eventName] = newEvent;}
+ events[eventName] = newEvent;
break;
- case "subscribeToEvent":
- {let eventName = messageArgs[0];
- let subscriberName = messageArgs[1];
- let newSubscriber = messageArgs[2];
- events[eventName]("addSubscriber", subscriberName, newSubscriber);}
+ }
+ case "subscribeToEvent": {
+ let [eventName, subscriberName, newSubscriber] = messageArgs;
+ events[eventName]("addSubscriber", subscriberName, newSubscriber);
break;
- case 'start':
+ }
+ case 'start': {
tick();
break;
- case 'halt':
+ }
+ case 'halt': {
halt();
break;
+ }
};
};
})();
+initTransformSystem(engine);
inputSystem(engine);
playerSystem(engine);
diff --git a/static/index.html b/static/index.html
index 4d68ab9..07e9d78 100644
--- a/static/index.html
+++ b/static/index.html
@@ -8,11 +8,19 @@
+
+
diff --git a/static/input.js b/static/input.js
index 44e7f20..1397b68 100644
--- a/static/input.js
+++ b/static/input.js
@@ -1,5 +1,8 @@
console.log("loading input system");
+const inputStates = Object.freeze({
+ DEFAULT: 0,
+});
const inputSystem = (engine) => {
engine("registerEvent", "moveDown");
@@ -7,21 +10,44 @@ const inputSystem = (engine) => {
engine("registerEvent", "moveLeft");
engine("registerEvent", "moveRight");
+ let state = inputStates.DEFAULT;
+ let currentPresses = new Set();
+
+ const stateEvents = {};
+ stateEvents[inputStates.DEFAULT] = {
+ ArrowDown: () => engine("queueEvent", "moveDown"),
+ ArrowUp: () => engine("queueEvent", "moveUp"),
+ ArrowLeft: () => engine("queueEvent", "moveLeft",),
+ ArrowRight: () => engine("queueEvent", "moveRight")
+ };
+
+ const process = () => {
+ currentPresses.forEach(press => {
+ // nop function for unmapped keypresses
+ (stateEvents[state][press] || (() => null))();
+ });
+ };
+
document.addEventListener('keydown', (event) => {
- let target = event.target;
- switch (event.key) {
- case "ArrowDown":
- engine("queueEvent", "moveDown", {target});
- break;
- case "ArrowUp":
- engine("queueEvent", "moveUp", {target});
- break;
- case "ArrowLeft":
- engine("queueEvent", "moveLeft", {target});
- break;
- case "ArrowRight":
- engine("queueEvent", "moveRight", {target});
+ currentPresses.add(event.key);
+ process();
+ });
+
+ document.addEventListener('keyup', (event) => {
+ currentPresses.delete(event.key);
+ process();
+ });
+
+ return (message, ...messageArgs) => {
+ switch (message) {
+ case "inputState": {
+ return state;
+ }
+ case "setInputState": {
+ let stateKey = messageArgs[0];
+ state = inputStates[stateKey];
break;
}
- });
+ };
+ };
};
diff --git a/static/player.js b/static/player.js
index bee8b8d..eee9302 100644
--- a/static/player.js
+++ b/static/player.js
@@ -1,34 +1,88 @@
console.log("loading player system");
const renderPlayer = (entity) => {
- entity.style.left = `${entity.dataset.posX}px`;
- entity.style.top = `${entity.dataset.posY}px`;
+ entity.style.transform = `matrix(${entity.dataset.transform.replace(/\[|\]/g,'')})`;
+ // entity.style.left = `${entity.dataset.posX}px`;
+ // entity.style.top = `${entity.dataset.posY}px`;
+};
+
+const setEntityStyleFromTransform = (entity) => {
+ entity.style.transform = `matrix(${entity.dataset.transform.replace(/\[|\]/g,'')})`;
+};
+
+const transform =
+ (entity,
+ transformData = { x: {x: 1, y:0}, y: {x:0, y:1}, o: {x:0,y:0}}
+ ) => {
+ let {x, y, o} = transformData;
+ let transform = [x.x, x.y, y.x, y.y, o.x, o.y];
+ const updateEntity = () => {
+ entity.dataset.transform = JSON.stringify (transform);
+ };
+ const renderEntity = () => setEntityStyleFromTransform (entity);
+
+ return (message, ...messageArgs) => {
+ switch (message) {
+ case "origin": {
+ return [transform[4], transform[5]];
+ }
+ case "x": {
+ return [transform[0], transform[1]];
+ }
+ case "y": {
+ return [transform[2], transform [3]];
+ }
+ case "translate": {
+ let [xTranslation, yTranslation] = messageArgs [0];
+ transform [4] += xTranslation;
+ transform [5] += yTranslation;
+ break;
+ }
+ }
+ updateEntity ();
+ renderEntity ();
+ };
+};
+
+// transform needs to actually provide transformation utilities
+
+const collision = (entity) => {
+ // look through engine's collision components for overlap
+
+};
+
+const initTransformSystem = (engine) => {
+ engine("registerComponentType", "transform");
};
const playerSystem = (engine) => {
const entity = document.getElementById("player");
engine("registerEntity", entity);
+ let playerTransform = transform(entity);
const movementRate = 0.5;
const move = (direction) => (delta, eventData) => {
- let lastPos = [Number(entity.dataset.posX), Number(entity.dataset.posY)];
+ let translation = [0,0];
switch (direction) {
case "left":
- entity.dataset.posX = Number(lastPos[0] - (movementRate * delta));
+ translation [0] = -( movementRate * delta );
break;
case "right":
- entity.dataset.posX = Number(lastPos[0] + (movementRate * delta));
+ translation[0] = movementRate * delta;
break;
case "up":
- entity.dataset.posY = Number(lastPos[1] - (movementRate * delta));
+ translation[1] = - ( movementRate * delta );
break;
case "down":
- entity.dataset.posY = Number(lastPos[1] + (movementRate * delta));
+ translation[1] = movementRate * delta;
break;
}
- renderPlayer(entity);
+ playerTransform("translate", translation);
};
+ engine("registerEntity", entity);
+ engine("addComponent", entity, "transform", playerTransform);
+ // engine("")
engine("subscribeToEvent", "moveLeft", "movePlayerLeft", move("left"));
engine("subscribeToEvent", "moveRight", "movePlayerRight", move("right"));
engine("subscribeToEvent", "moveUp", "movePlayerUp", move("up"));