init transform and state-based input

This commit is contained in:
sorrel 2024-05-19 18:07:43 -04:00
parent 0f66e7198b
commit 7d3828f894
4 changed files with 165 additions and 38 deletions

View file

@ -26,6 +26,7 @@ const engine = (() => {
let timer; let timer;
let time = Date.now(); let time = Date.now();
let entities = {}; let entities = {};
let components = {};
let events = {}; let events = {};
const engineTick = 1000 / 60; const engineTick = 1000 / 60;
@ -45,37 +46,75 @@ const engine = (() => {
}; };
return (message, ...messageArgs) => { return (message, ...messageArgs) => {
switch (message) { switch (message) {
case "queueEvent": case "queueEvent": {
queue.push(messageArgs[0]); queue.push(messageArgs[0]);
break; break;
case "events": }
case "events": {
return 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; 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; break;
case "removeEntity": }
case "registerComponentType": {
let componentType = messageArgs[0];
components[componentType] = new Set();
break; 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(); let newEvent = initEvent();
events[eventName] = newEvent;} events[eventName] = newEvent;
break; break;
case "subscribeToEvent": }
{let eventName = messageArgs[0]; case "subscribeToEvent": {
let subscriberName = messageArgs[1]; let [eventName, subscriberName, newSubscriber] = messageArgs;
let newSubscriber = messageArgs[2]; events[eventName]("addSubscriber", subscriberName, newSubscriber);
events[eventName]("addSubscriber", subscriberName, newSubscriber);}
break; break;
case 'start': }
case 'start': {
tick(); tick();
break; break;
case 'halt': }
case 'halt': {
halt(); halt();
break; break;
}
}; };
}; };
})(); })();
initTransformSystem(engine);
inputSystem(engine); inputSystem(engine);
playerSystem(engine); playerSystem(engine);

View file

@ -8,11 +8,19 @@
<body> <body>
<div class="player" <div class="player"
data-sprite="player.png" data-sprite="player.png"
data-pos-x="0" data-transform="[1,0,0,1,0,0]"
data-pos-y="0" data-collision="player"
id="player" id="player"
style="position:absolute;width:50px;height:50px;background-color:black;"></div> style="position:absolute;width:50px;height:50px;background-color:black;"></div>
<article class="level" id="test"> <article class="level" id="test">
<div class="environment"
data-collision="environment"
data-pos-x="0"
data-pos-y="0"
data-height="100"
data-width="100"
>
</div>
<table class="enemy" id="table-enemy" > <table class="enemy" id="table-enemy" >
<tbody> <tbody>
<tr> <tr>

View file

@ -1,5 +1,8 @@
console.log("loading input system"); console.log("loading input system");
const inputStates = Object.freeze({
DEFAULT: 0,
});
const inputSystem = (engine) => { const inputSystem = (engine) => {
engine("registerEvent", "moveDown"); engine("registerEvent", "moveDown");
@ -7,21 +10,44 @@ const inputSystem = (engine) => {
engine("registerEvent", "moveLeft"); engine("registerEvent", "moveLeft");
engine("registerEvent", "moveRight"); 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) => { document.addEventListener('keydown', (event) => {
let target = event.target; currentPresses.add(event.key);
switch (event.key) { process();
case "ArrowDown": });
engine("queueEvent", "moveDown", {target});
break; document.addEventListener('keyup', (event) => {
case "ArrowUp": currentPresses.delete(event.key);
engine("queueEvent", "moveUp", {target}); process();
break; });
case "ArrowLeft":
engine("queueEvent", "moveLeft", {target}); return (message, ...messageArgs) => {
break; switch (message) {
case "ArrowRight": case "inputState": {
engine("queueEvent", "moveRight", {target}); return state;
}
case "setInputState": {
let stateKey = messageArgs[0];
state = inputStates[stateKey];
break; break;
} }
}); };
};
}; };

View file

@ -1,34 +1,88 @@
console.log("loading player system"); console.log("loading player system");
const renderPlayer = (entity) => { const renderPlayer = (entity) => {
entity.style.left = `${entity.dataset.posX}px`; entity.style.transform = `matrix(${entity.dataset.transform.replace(/\[|\]/g,'')})`;
entity.style.top = `${entity.dataset.posY}px`; // 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 playerSystem = (engine) => {
const entity = document.getElementById("player"); const entity = document.getElementById("player");
engine("registerEntity", entity); engine("registerEntity", entity);
let playerTransform = transform(entity);
const movementRate = 0.5; const movementRate = 0.5;
const move = (direction) => (delta, eventData) => { const move = (direction) => (delta, eventData) => {
let lastPos = [Number(entity.dataset.posX), Number(entity.dataset.posY)]; let translation = [0,0];
switch (direction) { switch (direction) {
case "left": case "left":
entity.dataset.posX = Number(lastPos[0] - (movementRate * delta)); translation [0] = -( movementRate * delta );
break; break;
case "right": case "right":
entity.dataset.posX = Number(lastPos[0] + (movementRate * delta)); translation[0] = movementRate * delta;
break; break;
case "up": case "up":
entity.dataset.posY = Number(lastPos[1] - (movementRate * delta)); translation[1] = - ( movementRate * delta );
break; break;
case "down": case "down":
entity.dataset.posY = Number(lastPos[1] + (movementRate * delta)); translation[1] = movementRate * delta;
break; break;
} }
renderPlayer(entity); playerTransform("translate", translation);
}; };
engine("registerEntity", entity);
engine("addComponent", entity, "transform", playerTransform);
// engine("")
engine("subscribeToEvent", "moveLeft", "movePlayerLeft", move("left")); engine("subscribeToEvent", "moveLeft", "movePlayerLeft", move("left"));
engine("subscribeToEvent", "moveRight", "movePlayerRight", move("right")); engine("subscribeToEvent", "moveRight", "movePlayerRight", move("right"));
engine("subscribeToEvent", "moveUp", "movePlayerUp", move("up")); engine("subscribeToEvent", "moveUp", "movePlayerUp", move("up"));