UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers from the team at Phaser Studio Inc.

154 lines (136 loc) 5.16 kB
var Matter = require('../../CustomMain'); /** * An attractors plugin for matter.js. * See the readme for usage and examples. * @module MatterAttractors */ var MatterAttractors = { name: 'matter-attractors', version: '0.1.7', for: 'matter-js@^0.19.0', silent: true, // installs the plugin where `base` is `Matter` // you should not need to call this directly. install: function (base) { base.after('Body.create', function () { MatterAttractors.Body.init(this); }); base.before('Engine.update', function (engine) { MatterAttractors.Engine.update(engine); }); }, Body: { /** * Initialises the `body` to support attractors. * This is called automatically by the plugin. * @function MatterAttractors.Body.init * @param {Matter.Body} body The body to init. * @returns {void} No return value. */ init: function (body) { body.plugin.attractors = body.plugin.attractors || []; } }, Engine: { /** * Applies all attractors for all bodies in the `engine`. * This is called automatically by the plugin. * @function MatterAttractors.Engine.update * @param {Matter.Engine} engine The engine to update. * @returns {void} No return value. */ update: function (engine) { var bodies = Matter.Composite.allBodies(engine.world); for (var i = 0; i < bodies.length; i++) { var bodyA = bodies[i]; var attractors = bodyA.plugin.attractors; if (attractors && attractors.length > 0) { for (var j = 0; j < bodies.length; j++) { var bodyB = bodies[j]; if (i !== j) { for (var k = 0; k < attractors.length; k++) { var attractor = attractors[k]; var forceVector = attractor; if (Matter.Common.isFunction(attractor)) { forceVector = attractor(bodyA, bodyB); } if (forceVector) { Matter.Body.applyForce(bodyB, bodyB.position, forceVector); } } } } } } } }, /** * Defines some useful common attractor functions that can be used * by pushing them to your body's `body.plugin.attractors` array. * @namespace MatterAttractors.Attractors * @property {number} gravityConstant The gravitational constant used by the gravity attractor. */ Attractors: { gravityConstant: 0.001, /** * An attractor function that applies Newton's law of gravitation. * Use this by pushing `MatterAttractors.Attractors.gravity` to your body's `body.plugin.attractors` array. * The gravitational constant defaults to `0.001` which you can change * at `MatterAttractors.Attractors.gravityConstant`. * @function MatterAttractors.Attractors.gravity * @param {Matter.Body} bodyA The first body. * @param {Matter.Body} bodyB The second body. * @returns {void} No return value. */ gravity: function (bodyA, bodyB) { // use Newton's law of gravitation var bToA = Matter.Vector.sub(bodyB.position, bodyA.position); var distanceSq = Matter.Vector.magnitudeSquared(bToA) || 0.0001; var normal = Matter.Vector.normalise(bToA); var magnitude = -MatterAttractors.Attractors.gravityConstant * (bodyA.mass * bodyB.mass / distanceSq); var force = Matter.Vector.mult(normal, magnitude); // to apply forces to both bodies Matter.Body.applyForce(bodyA, bodyA.position, Matter.Vector.neg(force)); Matter.Body.applyForce(bodyB, bodyB.position, force); } } }; module.exports = MatterAttractors; /** * @namespace Matter.Body * @see http://brm.io/matter-js/docs/classes/Body.html */ /** * This plugin adds a new property `body.plugin.attractors` to instances of `Matter.Body`. * This is an array of callback functions that will be called automatically * for every pair of bodies, on every engine update. * @property {Function[]} body.plugin.attractors * @memberof Matter.Body */ /** * An attractor function calculates the force to be applied * to `bodyB`, it should either: * - return the force vector to be applied to `bodyB` * - or apply the force to the body(s) itself * @callback AttractorFunction * @param {Matter.Body} bodyA * @param {Matter.Body} bodyB * @returns {(Vector|undefined)} a force vector (optional) */