feat: Control locking

This commit is contained in:
cha0s 2024-06-25 10:44:37 -05:00
parent cadabc219d
commit 13b2a63f07
14 changed files with 128 additions and 50 deletions

View File

@ -1,4 +1,5 @@
export default { export default {
locked: {type: 'uint8'},
moveUp: {type: 'float32'}, moveUp: {type: 'float32'},
moveRight: {type: 'float32'}, moveRight: {type: 'float32'},
moveDown: {type: 'float32'}, moveDown: {type: 'float32'},

View File

@ -0,0 +1,4 @@
export default {
impulseX: {type: 'float32'},
impulseY: {type: 'float32'},
}

View File

@ -1,4 +0,0 @@
export default {
x: {type: 'float32'},
y: {type: 'float32'},
}

View File

@ -2,10 +2,23 @@ import {System} from '@/ecs/index.js';
export default class ApplyControlMovement extends System { export default class ApplyControlMovement extends System {
static get priority() {
return {
before: 'ApplyForces',
};
}
static queries() {
return {
default: ['Controlled', 'Forces', 'Speed'],
};
}
tick() { tick() {
for (const {Controlled, Momentum, Speed} of this.ecs.changed(['Controlled'])) { for (const [Controlled, Forces, Speed] of this.select('default')) {
Momentum.x = Speed.speed * (Controlled.moveRight - Controlled.moveLeft); if (!Controlled.locked) {
Momentum.y = Speed.speed * (Controlled.moveDown - Controlled.moveUp); Forces.impulseX += Speed.speed * (Controlled.moveRight - Controlled.moveLeft);
Forces.impulseY += Speed.speed * (Controlled.moveDown - Controlled.moveUp);
}
} }
} }

View File

@ -0,0 +1,18 @@
import {System} from '@/ecs/index.js';
export default class ApplyForces extends System {
static queries() {
return {
default: ['Position', 'Forces'],
};
}
tick(elapsed) {
for (const [Position, Forces] of this.select('default')) {
Position.x += elapsed * Forces.impulseX;
Position.y += elapsed * Forces.impulseY;
}
}
}

View File

@ -1,18 +0,0 @@
import {System} from '@/ecs/index.js';
export default class ApplyMomentum extends System {
static queries() {
return {
default: ['Position', 'Momentum'],
};
}
tick(elapsed) {
for (const [position, momentum] of this.select('default')) {
position.x += elapsed * momentum.x;
position.y += elapsed * momentum.y;
}
}
}

View File

@ -2,6 +2,12 @@ import {System} from '@/ecs/index.js';
export default class ClampPositions extends System { export default class ClampPositions extends System {
static get priority() {
return {
after: 'ApplyForces',
}
}
tick() { tick() {
const {AreaSize} = this.ecs.get(1); const {AreaSize} = this.ecs.get(1);
for (const {Position} of this.ecs.changed(['Position'])) { for (const {Position} of this.ecs.changed(['Position'])) {

View File

@ -4,7 +4,10 @@ export default class ControlDirection extends System {
tick() { tick() {
for (const {Controlled, Direction} of this.ecs.changed(['Controlled'])) { for (const {Controlled, Direction} of this.ecs.changed(['Controlled'])) {
const {moveUp, moveRight, moveDown, moveLeft} = Controlled; const {locked, moveUp, moveRight, moveDown, moveLeft} = Controlled;
if (locked) {
continue;
}
if (moveUp > 0) { if (moveUp > 0) {
Direction.direction = 0; Direction.direction = 0;
} }

View File

@ -0,0 +1,22 @@
import {System} from '@/ecs/index.js';
export default class ResetForces extends System {
static get priority() {
return {phase: 'pre'};
}
static queries() {
return {
default: ['Forces'],
};
}
tick() {
for (const [Forces] of this.select('default')) {
Forces.impulseX = 0;
Forces.impulseY = 0;
}
}
}

View File

@ -2,6 +2,12 @@ import {System} from '@/ecs/index.js';
export default class RunTickingPromises extends System { export default class RunTickingPromises extends System {
static get priority() {
return {
phase: 'pre',
};
}
static queries() { static queries() {
return { return {
default: ['Ticking'], default: ['Ticking'],

View File

@ -13,8 +13,8 @@ export default class SpriteDirection extends System {
const entity = this.ecs.get(entityId); const entity = this.ecs.get(entityId);
const parts = []; const parts = [];
if (entity.Controlled) { if (entity.Controlled) {
const {moveUp, moveRight, moveDown, moveLeft} = entity.Controlled; const {locked, moveUp, moveRight, moveDown, moveLeft} = entity.Controlled;
if (moveUp > 0 || moveRight > 0 || moveDown > 0 || moveLeft > 0) { if (!locked && (moveUp > 0 || moveRight > 0 || moveDown > 0 || moveLeft > 0)) {
parts.push('moving'); parts.push('moving');
} }
else { else {

View File

@ -85,8 +85,9 @@ export default class Engine {
}, },
}); });
const defaultSystems = [ const defaultSystems = [
'ResetForces',
'ApplyControlMovement', 'ApplyControlMovement',
'ApplyMomentum', 'ApplyForces',
'ClampPositions', 'ClampPositions',
'FollowCamera', 'FollowCamera',
'CalculateAabbs', 'CalculateAabbs',
@ -111,7 +112,7 @@ export default class Engine {
Controlled: {}, Controlled: {},
Direction: {direction: 2}, Direction: {direction: 2},
Ecs: {path: join('homesteads', `${id}`)}, Ecs: {path: join('homesteads', `${id}`)},
Momentum: {}, Forces: {},
Inventory: { Inventory: {
slots: { slots: {
1: { 1: {
@ -233,7 +234,9 @@ export default class Engine {
const {Controlled, Inventory, Ticking, Wielder} = entity; const {Controlled, Inventory, Ticking, Wielder} = entity;
switch (payload.type) { switch (payload.type) {
case 'changeSlot': { case 'changeSlot': {
Wielder.activeSlot = payload.value - 1; if (!Controlled.locked) {
Wielder.activeSlot = payload.value - 1;
}
break; break;
} }
case 'moveUp': case 'moveUp':
@ -244,28 +247,33 @@ export default class Engine {
break; break;
} }
case 'swapSlots': { case 'swapSlots': {
Inventory.swapSlots(...payload.value); if (!Controlled.locked) {
Inventory.swapSlots(...payload.value);
}
break; break;
} }
case 'use': { case 'use': {
Inventory.item(Wielder.activeSlot + 1).then(async (item) => { if (!Controlled.locked) {
if (item) { Inventory.item(Wielder.activeSlot + 1).then(async (item) => {
const code = await( if (item) {
this.server.readAsset([ const code = await(
item.source, this.server.readAsset([
payload.value ? 'start.js' : 'stop.js', item.source,
].join('/')) payload.value ? 'start.js' : 'stop.js',
.then((script) => (script.ok ? script.text() : '')) ].join('/'))
); .then((script) => (script.ok ? script.text() : ''))
if (code) { );
const context = { if (code) {
item, const context = {
wielder: entity, ecs: this.ecses[entity.Ecs.path],
}; item,
Ticking.addTickingPromise(Script.tickingPromise(code, context)); wielder: entity,
};
Ticking.addTickingPromise(Script.tickingPromise(code, context));
}
} }
} });
}); }
break; break;
} }
} }

View File

@ -30,7 +30,7 @@ test('visibility-based updates', async () => {
const ecs = engine.ecses['homesteads/0']; const ecs = engine.ecses['homesteads/0'];
// Create an entity. // Create an entity.
const entity = ecs.get(ecs.create({ const entity = ecs.get(ecs.create({
Momentum: {x: 1, y: 0}, Forces: {momentum: {x: 1, y: 0}},
Position: {x: (RESOLUTION.x * 1.5) + 32 - 3, y: 20}, Position: {x: (RESOLUTION.x * 1.5) + 32 - 3, y: 20},
VisibleAabb: {}, VisibleAabb: {},
})); }));

View File

@ -0,0 +1,19 @@
const {Controlled, Position, Wielder} = wielder
const {TileLayers} = ecs.get(1)
const layer = TileLayers.layer(0)
const projected = Wielder.project(Position.tile, item.tool.projection)
Controlled.locked = 1;
await wait(1000)
for (let i = 0; i < projected.length; ++i) {
if ([1, 2, 3, 4].includes(layer.tile(projected[i]))) {
layer.stamp(projected[i], [[6]])
}
else if ([6].includes(layer.tile(projected[i]))) {
layer.stamp(projected[i], [[7]])
}
}
Controlled.locked = 0;