import { System } from '@serpentity/serpentity'; const internals = { kTightStiffness: 0.001, kBaseStiffness: 0.0008, kLooseStiffness: 0.0000001 }; import ElasticNode from '../nodes/elastic'; /** Changes the stiffness on the node when it's less extended * * @extends {external:Serpentity.System} * @class ElasticSystem * @param {object} config a configuration object to extend. */ export default class ElasticSystem extends System { constructor(config = {}) { super(); /** * The node collection of entities that have external force * * @property {external:Serpentity.NodeCollection} elastics * @instance * @memberof ElasticSystem */ this.elastics = null; } /** * Initializes system when added. Requests elastic nodes * * @function added * @memberof ElasticSystem * @instance * @param {external:Serpentity.Engine} engine the serpentity engine to * which we are getting added */ added(engine) { this.elastics = engine.getNodes(ElasticNode); } /** * Clears system resources when removed. * * @function removed * @instance * @memberof ElasticSystem */ removed() { this.elastics = null; } /** * Runs on every update of the loop. Checks length of elastic and adjusts * stiffness * * @function update * @instance * @param {Number} currentFrameDuration the duration of the current * frame * @memberof ElasticSystem */ update(currentFrameDuration) { for (const elastic of this.elastics) { const constraint = elastic.body.body; const currentDistance = Math.abs( Math.sqrt( Math.pow(constraint.bodyA.position.x - constraint.bodyB.position.x, 2) + Math.pow(constraint.bodyA.position.y - constraint.bodyB.position.y, 2))); if (currentDistance <= constraint.length) { constraint.stiffness = internals.kLooseStiffness; continue; } if (currentDistance >= 2.6 * constraint.length) { constraint.stiffness = internals.kTightStiffness; continue; } constraint.stiffness = internals.kBaseStiffness; } } }