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

View file

@ -8,11 +8,19 @@
<body>
<div class="player"
data-sprite="player.png"
data-pos-x="0"
data-pos-y="0"
data-transform="[1,0,0,1,0,0]"
data-collision="player"
id="player"
style="position:absolute;width:50px;height:50px;background-color:black;"></div>
<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" >
<tbody>
<tr>

View file

@ -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");
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});
break;
}
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) => {
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;
}
};
};
};

View file

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