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"));