refactor: physics

This commit is contained in:
cha0s 2024-07-02 08:05:36 -05:00
parent 1d6d4449fd
commit fe44c1a4df
8 changed files with 50 additions and 8 deletions

View File

@ -1,7 +1,21 @@
import Component from '@/ecs/component.js';
export default class Forces extends Component {
instanceFromSchema() {
return class ForcesInstance extends super.instanceFromSchema() {
applyForce({x, y}) {
this.forceX += x;
this.forceY += y;
}
applyImpulse({x, y}) {
this.impulseX += x;
this.impulseY += y;
}
}
}
static properties = {
dampingX: {type: 'float32'},
dampingY: {type: 'float32'},
forceX: {type: 'float32'},
forceY: {type: 'float32'},
impulseX: {type: 'float32'},

View File

@ -1,10 +1,11 @@
import {System} from '@/ecs/index.js';
import {normalizeVector} from '@/util/math.js';
export default class ApplyControlMovement extends System {
static get priority() {
return {
before: 'ApplyForces',
before: 'IntegratePhysics',
};
}
@ -16,8 +17,14 @@ export default class ApplyControlMovement extends System {
tick() {
for (const {Controlled, Forces, Speed} of this.select('default')) {
if (!Controlled.locked) {
Forces.impulseX += Speed.speed * (Controlled.moveRight - Controlled.moveLeft);
Forces.impulseY += Speed.speed * (Controlled.moveDown - Controlled.moveUp);
const movement = normalizeVector({
x: (Controlled.moveRight - Controlled.moveLeft),
y: (Controlled.moveDown - Controlled.moveUp),
});
Forces.applyImpulse({
x: Speed.speed * movement.x,
y: Speed.speed * movement.y,
});
}
}
}

View File

@ -4,7 +4,7 @@ export default class CalculateAabbs extends System {
static get priority() {
return {
after: 'ApplyForces',
after: 'IntegratePhysics',
};
}

View File

@ -4,7 +4,7 @@ export default class ClampPositions extends System {
static get priority() {
return {
after: 'ApplyForces',
after: 'IntegratePhysics',
}
}

View File

@ -1,6 +1,6 @@
import {System} from '@/ecs/index.js';
export default class ApplyForces extends System {
export default class IntegratePhysics extends System {
static queries() {
return {

View File

@ -12,8 +12,22 @@ export default class ResetForces extends System {
};
}
tick() {
tick(elapsed) {
for (const {Forces} of this.select('default')) {
if (0 !== Forces.forceX) {
const factorX = Math.pow(1 - Forces.dampingX, elapsed);
Forces.forceX *= factorX;
if (Math.abs(Forces.forceX) <= 1) {
Forces.forceX = 0;
}
}
if (0 !== Forces.forceY) {
const factorY = Math.pow(1 - Forces.dampingY, elapsed);
Forces.forceY *= factorY;
if (Math.abs(Forces.forceY) <= 1) {
Forces.forceY = 0;
}
}
Forces.impulseX = 0;
Forces.impulseY = 0;
}

View File

@ -153,7 +153,7 @@ export default class Engine {
const defaultSystems = [
'ResetForces',
'ApplyControlMovement',
'ApplyForces',
'IntegratePhysics',
'ClampPositions',
'PlantGrowth',
'FollowCamera',

7
app/util/math.js Normal file
View File

@ -0,0 +1,7 @@
export function normalizeVector({x, y}) {
if (0 === y && 0 === x) {
return {x: 0, y: 0};
}
const k = 1 / Math.sqrt(x * x + y * y);
return {x: x * k, y: y * k};
}