From 4fc201d392db75150ac346fbbe1282e43577670e Mon Sep 17 00:00:00 2001 From: cha0s Date: Tue, 23 Mar 2021 06:09:47 -0500 Subject: [PATCH] refactor: better physics simulation --- packages/physics/src/matter/body.js | 6 +++++- packages/physics/src/matter/world.js | 6 ++++-- packages/physics/src/traits/physical.js | 27 +++++++++++++++++++++---- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/packages/physics/src/matter/body.js b/packages/physics/src/matter/body.js index 427b042..cc79a8d 100644 --- a/packages/physics/src/matter/body.js +++ b/packages/physics/src/matter/body.js @@ -11,7 +11,7 @@ import CircleShape from '../shape/circle'; import RectangleShape from '../shape/rectangle'; // Translate "real" coordinates to physics coordinates. -const SCALE = 1; +const SCALE = 1 / 12; export default class Body extends AbstractBody { @@ -106,6 +106,10 @@ export default class Body extends AbstractBody { return this.filterCategories[group]; } + set friction(friction) { + MatterBody.set(this.matterBody, 'frictionAir', friction); + } + static lookupBody(matterBody) { return this.bodies ? this.bodies.get(matterBody) diff --git a/packages/physics/src/matter/world.js b/packages/physics/src/matter/world.js index 7d44c25..764e9b9 100644 --- a/packages/physics/src/matter/world.js +++ b/packages/physics/src/matter/world.js @@ -76,8 +76,10 @@ export default class World extends AbstractWorld { const it = this.entities.entries(); for (let value = it.next(); value.done !== true; value = it.next()) { const [body] = value.value; - const [x, y] = Vector.scale(body.impulse, stepTime); - MatterBody.translate(body.matterBody, {x, y}); + const [x, y] = Vector.scale(body.impulse, stepTime / (1 - body.matterBody.frictionAir)); + if (x || y) { + MatterBody.setVelocity(body.matterBody, {x, y}); + } } Engine.update(this.engine, stepTimeInMs); // eslint-disable-next-line no-param-reassign diff --git a/packages/physics/src/traits/physical.js b/packages/physics/src/traits/physical.js index 74ff8d6..6c3e628 100644 --- a/packages/physics/src/traits/physical.js +++ b/packages/physics/src/traits/physical.js @@ -1,9 +1,16 @@ import {Vector} from '@avocado/math'; -import {Trait} from '@avocado/traits'; +import {StateProperty, Trait} from '@avocado/traits'; +import {compose} from '@latus/core'; import BodyView from '../body-view'; -export default () => class Physical extends Trait { +const decorate = compose( + StateProperty('friction', { + track: true, + }), +); + +export default () => class Physical extends decorate(Trait) { #body; @@ -15,6 +22,7 @@ export default () => class Physical extends Trait { const world = this.#world; if (world) { const body = world.createBody(this.entity.shape); + body.friction = this.entity.friction; world.associateBodyWithEntity(body, this.entity); body.setCollisionForEntity(this.entity); world.addBody(body); @@ -64,6 +72,12 @@ export default () => class Physical extends Trait { }; } + static defaultState() { + return { + friction: 0.5, + }; + } + static dependencies() { return [ 'Shaped', @@ -86,10 +100,15 @@ export default () => class Physical extends Trait { this.removeFromWorld(); }, + frictionChanged: () => { + if (this.#body) { + this.#body.friction = this.entity.friction; + } + }, + positionChanged: () => { if (this.#body) { - const {position} = this.entity; - this.#body.position = position; + this.#body.position = this.entity.position; } },