mirror of
https://github.com/photonstorm/phaser
synced 2025-01-12 05:08:54 +00:00
1463 lines
51 KiB
JavaScript
1463 lines
51 KiB
JavaScript
/**
|
|
* @author Richard Davey <rich@photonstorm.com>
|
|
* @copyright 2020 Photon Storm Ltd.
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
|
*/
|
|
|
|
var ALIGN_CONST = require('../../display/align/const');
|
|
var Axes = require('./lib/geometry/Axes');
|
|
var Bodies = require('./lib/factory/Bodies');
|
|
var Body = require('./lib/body/Body');
|
|
var BodyBounds = require('./BodyBounds');
|
|
var Bounds = require('./lib/geometry/Bounds');
|
|
var Class = require('../../utils/Class');
|
|
var Composite = require('./lib/body/Composite');
|
|
var Composites = require('./lib/factory/Composites');
|
|
var Constraint = require('./lib/constraint/Constraint');
|
|
var Detector = require('./lib/collision/Detector');
|
|
var DistanceBetween = require('../../math/distance/DistanceBetween');
|
|
var Factory = require('./Factory');
|
|
var GetFastValue = require('../../utils/object/GetFastValue');
|
|
var GetValue = require('../../utils/object/GetValue');
|
|
var Grid = require('./lib/collision/Grid');
|
|
var MatterAttractors = require('./lib/plugins/MatterAttractors');
|
|
var MatterCollisionEvents = require('./lib/plugins/MatterCollisionEvents');
|
|
var MatterLib = require('./lib/core/Matter');
|
|
var MatterWrap = require('./lib/plugins/MatterWrap');
|
|
var Merge = require('../../utils/object/Merge');
|
|
var Pair = require('./lib/collision/Pair');
|
|
var Pairs = require('./lib/collision/Pairs');
|
|
var Plugin = require('./lib/core/Plugin');
|
|
var PluginCache = require('../../plugins/PluginCache');
|
|
var Query = require('./lib/collision/Query');
|
|
var Resolver = require('./lib/collision/Resolver');
|
|
var SAT = require('./lib/collision/SAT');
|
|
var SceneEvents = require('../../scene/events');
|
|
var Svg = require('./lib/geometry/Svg');
|
|
var Vector = require('./lib/geometry/Vector');
|
|
var Vertices = require('./lib/geometry/Vertices');
|
|
var World = require('./World');
|
|
|
|
/**
|
|
* @classdesc
|
|
* The Phaser Matter plugin provides the ability to use the Matter JS Physics Engine within your Phaser games.
|
|
*
|
|
* Unlike Arcade Physics, the other physics system provided with Phaser, Matter JS is a full-body physics system.
|
|
* It features:
|
|
*
|
|
* * Rigid bodies
|
|
* * Compound bodies
|
|
* * Composite bodies
|
|
* * Concave and convex hulls
|
|
* * Physical properties (mass, area, density etc.)
|
|
* * Restitution (elastic and inelastic collisions)
|
|
* * Collisions (broad-phase, mid-phase and narrow-phase)
|
|
* * Stable stacking and resting
|
|
* * Conservation of momentum
|
|
* * Friction and resistance
|
|
* * Constraints
|
|
* * Gravity
|
|
* * Sleeping and static bodies
|
|
* * Rounded corners (chamfering)
|
|
* * Views (translate, zoom)
|
|
* * Collision queries (raycasting, region tests)
|
|
* * Time scaling (slow-mo, speed-up)
|
|
*
|
|
* Configuration of Matter is handled via the Matter World Config object, which can be passed in either the
|
|
* Phaser Game Config, or Phaser Scene Config. Here is a basic example:
|
|
*
|
|
* ```js
|
|
* physics: {
|
|
* default: 'matter',
|
|
* matter: {
|
|
* enableSleeping: true,
|
|
* gravity: {
|
|
* y: 0
|
|
* },
|
|
* debug: {
|
|
* showBody: true,
|
|
* showStaticBody: true
|
|
* }
|
|
* }
|
|
* }
|
|
* ```
|
|
*
|
|
* This class acts as an interface between a Phaser Scene and a single instance of the Matter Engine.
|
|
*
|
|
* Use it to access the most common Matter features and helper functions.
|
|
*
|
|
* You can find details, documentation and examples on the Matter JS website: https://brm.io/matter-js/
|
|
*
|
|
* @class MatterPhysics
|
|
* @memberof Phaser.Physics.Matter
|
|
* @constructor
|
|
* @since 3.0.0
|
|
*
|
|
* @param {Phaser.Scene} scene - The Phaser Scene that owns this Matter Physics instance.
|
|
*/
|
|
var MatterPhysics = new Class({
|
|
|
|
initialize:
|
|
|
|
function MatterPhysics (scene)
|
|
{
|
|
/**
|
|
* The Phaser Scene that owns this Matter Physics instance
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#scene
|
|
* @type {Phaser.Scene}
|
|
* @since 3.0.0
|
|
*/
|
|
this.scene = scene;
|
|
|
|
/**
|
|
* A reference to the Scene Systems that belong to the Scene owning this Matter Physics instance.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#systems
|
|
* @type {Phaser.Scenes.Systems}
|
|
* @since 3.0.0
|
|
*/
|
|
this.systems = scene.sys;
|
|
|
|
/**
|
|
* The parsed Matter Configuration object.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#config
|
|
* @type {Phaser.Types.Physics.Matter.MatterWorldConfig}
|
|
* @since 3.0.0
|
|
*/
|
|
this.config = this.getConfig();
|
|
|
|
/**
|
|
* An instance of the Matter World class. This class is responsible for the updating of the
|
|
* Matter Physics world, as well as handling debug drawing functions.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#world
|
|
* @type {Phaser.Physics.Matter.World}
|
|
* @since 3.0.0
|
|
*/
|
|
this.world;
|
|
|
|
/**
|
|
* An instance of the Matter Factory. This class provides lots of functions for creating a
|
|
* wide variety of physics objects and adds them automatically to the Matter World.
|
|
*
|
|
* You can use this class to cut-down on the amount of code required in your game, however,
|
|
* use of the Factory is entirely optional and should be seen as a development aid. It's
|
|
* perfectly possible to create and add components to the Matter world without using it.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#add
|
|
* @type {Phaser.Physics.Matter.Factory}
|
|
* @since 3.0.0
|
|
*/
|
|
this.add;
|
|
|
|
/**
|
|
* An instance of the Body Bounds class. This class contains functions used for getting the
|
|
* world position from various points around the bounds of a physics body.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#bodyBounds
|
|
* @type {Phaser.Physics.Matter.BodyBounds}
|
|
* @since 3.22.0
|
|
*/
|
|
this.bodyBounds;
|
|
|
|
// Body
|
|
|
|
/**
|
|
* A reference to the `Matter.Body` module.
|
|
*
|
|
* The `Matter.Body` module contains methods for creating and manipulating body models.
|
|
* A `Matter.Body` is a rigid body that can be simulated by a `Matter.Engine`.
|
|
* Factories for commonly used body configurations (such as rectangles, circles and other polygons) can be found in the `Bodies` module.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#body
|
|
* @type {MatterJS.BodyFactory}
|
|
* @since 3.18.0
|
|
*/
|
|
this.body = Body;
|
|
|
|
/**
|
|
* A reference to the `Matter.Composite` module.
|
|
*
|
|
* The `Matter.Composite` module contains methods for creating and manipulating composite bodies.
|
|
* A composite body is a collection of `Matter.Body`, `Matter.Constraint` and other `Matter.Composite`, therefore composites form a tree structure.
|
|
* It is important to use the functions in this module to modify composites, rather than directly modifying their properties.
|
|
* Note that the `Matter.World` object is also a type of `Matter.Composite` and as such all composite methods here can also operate on a `Matter.World`.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#composite
|
|
* @type {MatterJS.CompositeFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.composite = Composite;
|
|
|
|
// Collision:
|
|
|
|
/**
|
|
* A reference to the `Matter.Detector` module.
|
|
*
|
|
* The `Matter.Detector` module contains methods for detecting collisions given a set of pairs.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#detector
|
|
* @type {MatterJS.DetectorFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.detector = Detector;
|
|
|
|
/**
|
|
* A reference to the `Matter.Grid` module.
|
|
*
|
|
* The `Matter.Grid` module contains methods for creating and manipulating collision broadphase grid structures.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#grid
|
|
* @type {MatterJS.GridFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.grid = Grid;
|
|
|
|
/**
|
|
* A reference to the `Matter.Pair` module.
|
|
*
|
|
* The `Matter.Pair` module contains methods for creating and manipulating collision pairs.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#pair
|
|
* @type {MatterJS.PairFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.pair = Pair;
|
|
|
|
/**
|
|
* A reference to the `Matter.Pairs` module.
|
|
*
|
|
* The `Matter.Pairs` module contains methods for creating and manipulating collision pair sets.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#pairs
|
|
* @type {MatterJS.PairsFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.pairs = Pairs;
|
|
|
|
/**
|
|
* A reference to the `Matter.Query` module.
|
|
*
|
|
* The `Matter.Query` module contains methods for performing collision queries.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#query
|
|
* @type {MatterJS.QueryFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.query = Query;
|
|
|
|
/**
|
|
* A reference to the `Matter.Resolver` module.
|
|
*
|
|
* The `Matter.Resolver` module contains methods for resolving collision pairs.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#resolver
|
|
* @type {MatterJS.ResolverFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.resolver = Resolver;
|
|
|
|
/**
|
|
* A reference to the `Matter.SAT` module.
|
|
*
|
|
* The `Matter.SAT` module contains methods for detecting collisions using the Separating Axis Theorem.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#sat
|
|
* @type {MatterJS.SATFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.sat = SAT;
|
|
|
|
// Constraint
|
|
|
|
/**
|
|
* A reference to the `Matter.Constraint` module.
|
|
*
|
|
* The `Matter.Constraint` module contains methods for creating and manipulating constraints.
|
|
* Constraints are used for specifying that a fixed distance must be maintained between two bodies (or a body and a fixed world-space position).
|
|
* The stiffness of constraints can be modified to create springs or elastic.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#constraint
|
|
* @type {MatterJS.ConstraintFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.constraint = Constraint;
|
|
|
|
// Factory
|
|
|
|
/**
|
|
* A reference to the `Matter.Bodies` module.
|
|
*
|
|
* The `Matter.Bodies` module contains factory methods for creating rigid bodies
|
|
* with commonly used body configurations (such as rectangles, circles and other polygons).
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#bodies
|
|
* @type {MatterJS.BodiesFactory}
|
|
* @since 3.18.0
|
|
*/
|
|
this.bodies = Bodies;
|
|
|
|
/**
|
|
* A reference to the `Matter.Composites` module.
|
|
*
|
|
* The `Matter.Composites` module contains factory methods for creating composite bodies
|
|
* with commonly used configurations (such as stacks and chains).
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#composites
|
|
* @type {MatterJS.CompositesFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.composites = Composites;
|
|
|
|
// Geometry
|
|
|
|
/**
|
|
* A reference to the `Matter.Axes` module.
|
|
*
|
|
* The `Matter.Axes` module contains methods for creating and manipulating sets of axes.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#axes
|
|
* @type {MatterJS.AxesFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.axes = Axes;
|
|
|
|
/**
|
|
* A reference to the `Matter.Bounds` module.
|
|
*
|
|
* The `Matter.Bounds` module contains methods for creating and manipulating axis-aligned bounding boxes (AABB).
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#bounds
|
|
* @type {MatterJS.BoundsFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.bounds = Bounds;
|
|
|
|
/**
|
|
* A reference to the `Matter.Svg` module.
|
|
*
|
|
* The `Matter.Svg` module contains methods for converting SVG images into an array of vector points.
|
|
*
|
|
* To use this module you also need the SVGPathSeg polyfill: https://github.com/progers/pathseg
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#svg
|
|
* @type {MatterJS.SvgFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.svg = Svg;
|
|
|
|
/**
|
|
* A reference to the `Matter.Vector` module.
|
|
*
|
|
* The `Matter.Vector` module contains methods for creating and manipulating vectors.
|
|
* Vectors are the basis of all the geometry related operations in the engine.
|
|
* A `Matter.Vector` object is of the form `{ x: 0, y: 0 }`.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#vector
|
|
* @type {MatterJS.VectorFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.vector = Vector;
|
|
|
|
/**
|
|
* A reference to the `Matter.Vertices` module.
|
|
*
|
|
* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
|
|
* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
|
|
* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#vertices
|
|
* @type {MatterJS.VerticesFactory}
|
|
* @since 3.22.0
|
|
*/
|
|
this.vertices = Vertices;
|
|
|
|
/**
|
|
* A reference to the `Matter.Vertices` module.
|
|
*
|
|
* The `Matter.Vertices` module contains methods for creating and manipulating sets of vertices.
|
|
* A set of vertices is an array of `Matter.Vector` with additional indexing properties inserted by `Vertices.create`.
|
|
* A `Matter.Body` maintains a set of vertices to represent the shape of the object (its convex hull).
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#verts
|
|
* @type {MatterJS.VerticesFactory}
|
|
* @since 3.14.0
|
|
*/
|
|
this.verts = Vertices;
|
|
|
|
/**
|
|
* An internal temp vector used for velocity and force calculations.
|
|
*
|
|
* @name Phaser.Physics.Matter.MatterPhysics#_tempVec2
|
|
* @type {MatterJS.Vector}
|
|
* @private
|
|
* @since 3.22.0
|
|
*/
|
|
this._tempVec2 = Vector.create();
|
|
|
|
// Matter plugins
|
|
|
|
if (GetValue(this.config, 'plugins.collisionevents', true))
|
|
{
|
|
this.enableCollisionEventsPlugin();
|
|
}
|
|
|
|
if (GetValue(this.config, 'plugins.attractors', false))
|
|
{
|
|
this.enableAttractorPlugin();
|
|
}
|
|
|
|
if (GetValue(this.config, 'plugins.wrap', false))
|
|
{
|
|
this.enableWrapPlugin();
|
|
}
|
|
|
|
Resolver._restingThresh = GetValue(this.config, 'restingThresh', 4);
|
|
Resolver._restingThreshTangent = GetValue(this.config, 'restingThreshTangent', 6);
|
|
Resolver._positionDampen = GetValue(this.config, 'positionDampen', 0.9);
|
|
Resolver._positionWarming = GetValue(this.config, 'positionWarming', 0.8);
|
|
Resolver._frictionNormalMultiplier = GetValue(this.config, 'frictionNormalMultiplier', 5);
|
|
|
|
scene.sys.events.once(SceneEvents.BOOT, this.boot, this);
|
|
scene.sys.events.on(SceneEvents.START, this.start, this);
|
|
},
|
|
|
|
/**
|
|
* This method is called automatically, only once, when the Scene is first created.
|
|
* Do not invoke it directly.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#boot
|
|
* @private
|
|
* @since 3.5.1
|
|
*/
|
|
boot: function ()
|
|
{
|
|
this.world = new World(this.scene, this.config);
|
|
this.add = new Factory(this.world);
|
|
this.bodyBounds = new BodyBounds();
|
|
|
|
this.systems.events.once(SceneEvents.DESTROY, this.destroy, this);
|
|
},
|
|
|
|
/**
|
|
* This method is called automatically by the Scene when it is starting up.
|
|
* It is responsible for creating local systems, properties and listening for Scene events.
|
|
* Do not invoke it directly.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#start
|
|
* @private
|
|
* @since 3.5.0
|
|
*/
|
|
start: function ()
|
|
{
|
|
if (!this.world)
|
|
{
|
|
this.world = new World(this.scene, this.config);
|
|
this.add = new Factory(this.world);
|
|
}
|
|
|
|
var eventEmitter = this.systems.events;
|
|
|
|
eventEmitter.on(SceneEvents.UPDATE, this.world.update, this.world);
|
|
eventEmitter.on(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world);
|
|
eventEmitter.once(SceneEvents.SHUTDOWN, this.shutdown, this);
|
|
},
|
|
|
|
/**
|
|
* This internal method is called when this class starts and retrieves the final Matter World Config.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#getConfig
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Types.Physics.Matter.MatterWorldConfig} The Matter World Config.
|
|
*/
|
|
getConfig: function ()
|
|
{
|
|
var gameConfig = this.systems.game.config.physics;
|
|
var sceneConfig = this.systems.settings.physics;
|
|
|
|
var config = Merge(
|
|
GetFastValue(sceneConfig, 'matter', {}),
|
|
GetFastValue(gameConfig, 'matter', {})
|
|
);
|
|
|
|
return config;
|
|
},
|
|
|
|
/**
|
|
* Enables the Matter Attractors Plugin.
|
|
*
|
|
* The attractors plugin that makes it easy to apply continual forces on bodies.
|
|
* It's possible to simulate effects such as wind, gravity and magnetism.
|
|
*
|
|
* https://github.com/liabru/matter-attractors
|
|
*
|
|
* This method is called automatically if `plugins.attractors` is set in the Matter World Config.
|
|
* However, you can also call it directly from within your game.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#enableAttractorPlugin
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
enableAttractorPlugin: function ()
|
|
{
|
|
Plugin.register(MatterAttractors);
|
|
Plugin.use(MatterLib, MatterAttractors);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Enables the Matter Wrap Plugin.
|
|
*
|
|
* The coordinate wrapping plugin that automatically wraps the position of bodies such that they always stay
|
|
* within the given bounds. Upon crossing a boundary the body will appear on the opposite side of the bounds,
|
|
* while maintaining its velocity.
|
|
*
|
|
* https://github.com/liabru/matter-wrap
|
|
*
|
|
* This method is called automatically if `plugins.wrap` is set in the Matter World Config.
|
|
* However, you can also call it directly from within your game.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#enableWrapPlugin
|
|
* @since 3.0.0
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
enableWrapPlugin: function ()
|
|
{
|
|
Plugin.register(MatterWrap);
|
|
Plugin.use(MatterLib, MatterWrap);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Enables the Matter Collision Events Plugin.
|
|
*
|
|
* Note that this plugin is enabled by default. So you should only ever need to call this
|
|
* method if you have specifically disabled the plugin in your Matter World Config.
|
|
* You can disable it by setting `plugins.collisionevents: false` in your Matter World Config.
|
|
*
|
|
* This plugin triggers three new events on Matter.Body:
|
|
*
|
|
* 1. `onCollide`
|
|
* 2. `onCollideEnd`
|
|
* 3. `onCollideActive`
|
|
*
|
|
* These events correspond to the Matter.js events `collisionStart`, `collisionActive` and `collisionEnd`, respectively.
|
|
* You can listen to these events via Matter.Events or they will also be emitted from the Matter World.
|
|
*
|
|
* This plugin also extends Matter.Body with three convenience functions:
|
|
*
|
|
* `Matter.Body.setOnCollide(callback)`
|
|
* `Matter.Body.setOnCollideEnd(callback)`
|
|
* `Matter.Body.setOnCollideActive(callback)`
|
|
*
|
|
* You can register event callbacks by providing a function of type (pair: Matter.Pair) => void
|
|
*
|
|
* https://github.com/dxu/matter-collision-events
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#enableCollisionEventsPlugin
|
|
* @since 3.22.0
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
enableCollisionEventsPlugin: function ()
|
|
{
|
|
Plugin.register(MatterCollisionEvents);
|
|
Plugin.use(MatterLib, MatterCollisionEvents);
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Pauses the Matter World instance and sets `enabled` to `false`.
|
|
*
|
|
* A paused world will not run any simulations for the duration it is paused.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#pause
|
|
* @fires Phaser.Physics.Matter.Events#PAUSE
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Physics.Matter.World} The Matter World object.
|
|
*/
|
|
pause: function ()
|
|
{
|
|
return this.world.pause();
|
|
},
|
|
|
|
/**
|
|
* Resumes this Matter World instance from a paused state and sets `enabled` to `true`.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#resume
|
|
* @since 3.0.0
|
|
*
|
|
* @return {Phaser.Physics.Matter.World} The Matter World object.
|
|
*/
|
|
resume: function ()
|
|
{
|
|
return this.world.resume();
|
|
},
|
|
|
|
/**
|
|
* Sets the Matter Engine to run at fixed timestep of 60Hz and enables `autoUpdate`.
|
|
* If you have set a custom `getDelta` function then this will override it.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#set60Hz
|
|
* @since 3.4.0
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
set60Hz: function ()
|
|
{
|
|
this.world.getDelta = this.world.update60Hz;
|
|
this.world.autoUpdate = true;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the Matter Engine to run at fixed timestep of 30Hz and enables `autoUpdate`.
|
|
* If you have set a custom `getDelta` function then this will override it.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#set30Hz
|
|
* @since 3.4.0
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
set30Hz: function ()
|
|
{
|
|
this.world.getDelta = this.world.update30Hz;
|
|
this.world.autoUpdate = true;
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Manually advances the physics simulation by one iteration.
|
|
*
|
|
* You can optionally pass in the `delta` and `correction` values to be used by Engine.update.
|
|
* If undefined they use the Matter defaults of 60Hz and no correction.
|
|
*
|
|
* Calling `step` directly bypasses any checks of `enabled` or `autoUpdate`.
|
|
*
|
|
* It also ignores any custom `getDelta` functions, as you should be passing the delta
|
|
* value in to this call.
|
|
*
|
|
* You can adjust the number of iterations that Engine.update performs internally.
|
|
* Use the Scene Matter Physics config object to set the following properties:
|
|
*
|
|
* positionIterations (defaults to 6)
|
|
* velocityIterations (defaults to 4)
|
|
* constraintIterations (defaults to 2)
|
|
*
|
|
* Adjusting these values can help performance in certain situations, depending on the physics requirements
|
|
* of your game.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#step
|
|
* @since 3.4.0
|
|
*
|
|
* @param {number} [delta=16.666] - The delta value.
|
|
* @param {number} [correction=1] - Optional delta correction value.
|
|
*/
|
|
step: function (delta, correction)
|
|
{
|
|
this.world.step(delta, correction);
|
|
},
|
|
|
|
/**
|
|
* Checks if the vertices of the given body, or an array of bodies, contains the given point, or not.
|
|
*
|
|
* You can pass in either a single body, or an array of bodies to be checked. This method will
|
|
* return `true` if _any_ of the bodies in the array contain the point. See the `intersectPoint` method if you need
|
|
* to get a list of intersecting bodies.
|
|
*
|
|
* The point should be transformed into the Matter World coordinate system in advance. This happens by
|
|
* default with Input Pointers, but if you wish to use points from another system you may need to
|
|
* transform them before passing them.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#containsPoint
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} body - The body, or an array of bodies, to check against the point.
|
|
* @param {number} x - The horizontal coordinate of the point.
|
|
* @param {number} y - The vertical coordinate of the point.
|
|
*
|
|
* @return {boolean} `true` if the point is within one of the bodies given, otherwise `false`.
|
|
*/
|
|
containsPoint: function (body, x, y)
|
|
{
|
|
body = this.getMatterBodies(body);
|
|
|
|
var position = Vector.create(x, y);
|
|
|
|
var result = Query.point(body, position);
|
|
|
|
return (result.length > 0) ? true : false;
|
|
},
|
|
|
|
/**
|
|
* Checks the given coordinates to see if any vertices of the given bodies contain it.
|
|
*
|
|
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
|
|
*
|
|
* The coordinates should be transformed into the Matter World coordinate system in advance. This happens by
|
|
* default with Input Pointers, but if you wish to use coordinates from another system you may need to
|
|
* transform them before passing them.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectPoint
|
|
* @since 3.22.0
|
|
*
|
|
* @param {number} x - The horizontal coordinate of the point.
|
|
* @param {number} y - The vertical coordinate of the point.
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
|
*
|
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies which contain the given point.
|
|
*/
|
|
intersectPoint: function (x, y, bodies)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var position = Vector.create(x, y);
|
|
|
|
var output = [];
|
|
|
|
var result = Query.point(bodies, position);
|
|
|
|
result.forEach(function (body)
|
|
{
|
|
if (output.indexOf(body) === -1)
|
|
{
|
|
output.push(body);
|
|
}
|
|
});
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Checks the given rectangular area to see if any vertices of the given bodies intersect with it.
|
|
* Or, if the `outside` parameter is set to `true`, it checks to see which bodies do not
|
|
* intersect with it.
|
|
*
|
|
* If no bodies are provided it will search all bodies in the Matter World, including within Composites.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectRect
|
|
* @since 3.22.0
|
|
*
|
|
* @param {number} x - The horizontal coordinate of the top-left of the area.
|
|
* @param {number} y - The vertical coordinate of the top-left of the area.
|
|
* @param {number} width - The width of the area.
|
|
* @param {number} height - The height of the area.
|
|
* @param {boolean} [outside=false] - If `false` it checks for vertices inside the area, if `true` it checks for vertices outside the area.
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
|
*
|
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies that intersect with the given area.
|
|
*/
|
|
intersectRect: function (x, y, width, height, outside, bodies)
|
|
{
|
|
if (outside === undefined) { outside = false; }
|
|
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var bounds = {
|
|
min: { x: x, y: y },
|
|
max: { x: x + width, y: y + height }
|
|
};
|
|
|
|
var output = [];
|
|
|
|
var result = Query.region(bodies, bounds, outside);
|
|
|
|
result.forEach(function (body)
|
|
{
|
|
if (output.indexOf(body) === -1)
|
|
{
|
|
output.push(body);
|
|
}
|
|
});
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Checks the given ray segment to see if any vertices of the given bodies intersect with it.
|
|
*
|
|
* If no bodies are provided it will search all bodies in the Matter World.
|
|
*
|
|
* The width of the ray can be specified via the `rayWidth` parameter.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectRay
|
|
* @since 3.22.0
|
|
*
|
|
* @param {number} x1 - The horizontal coordinate of the start of the ray segment.
|
|
* @param {number} y1 - The vertical coordinate of the start of the ray segment.
|
|
* @param {number} x2 - The horizontal coordinate of the end of the ray segment.
|
|
* @param {number} y2 - The vertical coordinate of the end of the ray segment.
|
|
* @param {number} [rayWidth=1] - The width of the ray segment.
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check. If not provided it will search all bodies in the world.
|
|
*
|
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with the ray segment.
|
|
*/
|
|
intersectRay: function (x1, y1, x2, y2, rayWidth, bodies)
|
|
{
|
|
if (rayWidth === undefined) { rayWidth = 1; }
|
|
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var result = [];
|
|
var collisions = Query.ray(bodies, Vector.create(x1, y1), Vector.create(x2, y2), rayWidth);
|
|
|
|
for (var i = 0; i < collisions.length; i++)
|
|
{
|
|
result.push(collisions[i].body);
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
/**
|
|
* Checks the given Matter Body to see if it intersects with any of the given bodies.
|
|
*
|
|
* If no bodies are provided it will check against all bodies in the Matter World.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#intersectBody
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The target body.
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - An array of bodies to check the target body against. If not provided it will search all bodies in the world.
|
|
*
|
|
* @return {Phaser.Types.Physics.Matter.MatterBody[]} An array of bodies whos vertices intersect with target body.
|
|
*/
|
|
intersectBody: function (body, bodies)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var result = [];
|
|
var collisions = Query.collides(body, bodies);
|
|
|
|
for (var i = 0; i < collisions.length; i++)
|
|
{
|
|
var pair = collisions[i];
|
|
|
|
if (pair.bodyA === body)
|
|
{
|
|
result.push(pair.bodyB);
|
|
}
|
|
else
|
|
{
|
|
result.push(pair.bodyA);
|
|
}
|
|
}
|
|
|
|
return result;
|
|
},
|
|
|
|
/**
|
|
* Checks to see if the target body, or an array of target bodies, intersects with any of the given bodies.
|
|
*
|
|
* If intersection occurs this method will return `true` and, if provided, invoke the callbacks.
|
|
*
|
|
* If no bodies are provided for the second parameter the target will check again all bodies in the Matter World.
|
|
*
|
|
* Note that bodies can only overlap if they are in non-colliding collision groups or categories.
|
|
*
|
|
* If you provide a `processCallback` then the two bodies that overlap are sent to it. This callback
|
|
* must return a boolean and is used to allow you to perform additional processing tests before a final
|
|
* outcome is decided. If it returns `true` then the bodies are finally passed to the `overlapCallback`, if set.
|
|
*
|
|
* If you provide an `overlapCallback` then the matching pairs of overlapping bodies will be sent to it.
|
|
*
|
|
* Both callbacks have the following signature: `function (bodyA, bodyB, collisionInfo)` where `bodyA` is always
|
|
* the target body. The `collisionInfo` object contains additional data, such as the angle and depth of penetration.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#overlap
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} target - The target body, or array of target bodies, to check.
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} [bodies] - The second body, or array of bodies, to check. If falsey it will check against all bodies in the world.
|
|
* @param {ArcadePhysicsCallback} [overlapCallback] - An optional callback function that is called if the bodies overlap.
|
|
* @param {ArcadePhysicsCallback} [processCallback] - An optional callback function that lets you perform additional checks against the two bodies if they overlap. If this is set then `overlapCallback` will only be invoked if this callback returns `true`.
|
|
* @param {*} [callbackContext] - The context, or scope, in which to run the callbacks.
|
|
*
|
|
* @return {boolean} `true` if the target body intersects with _any_ of the bodies given, otherwise `false`.
|
|
*/
|
|
overlap: function (target, bodies, overlapCallback, processCallback, callbackContext)
|
|
{
|
|
if (overlapCallback === undefined) { overlapCallback = null; }
|
|
if (processCallback === undefined) { processCallback = null; }
|
|
if (callbackContext === undefined) { callbackContext = overlapCallback; }
|
|
|
|
if (!Array.isArray(target))
|
|
{
|
|
target = [ target ];
|
|
}
|
|
|
|
target = this.getMatterBodies(target);
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var match = false;
|
|
|
|
for (var i = 0; i < target.length; i++)
|
|
{
|
|
var entry = target[i];
|
|
|
|
var collisions = Query.collides(entry, bodies);
|
|
|
|
for (var c = 0; c < collisions.length; c++)
|
|
{
|
|
var info = collisions[c];
|
|
var bodyB = (info.bodyA.id === entry.id) ? info.bodyB : info.bodyA;
|
|
|
|
if (!processCallback || processCallback.call(callbackContext, entry, bodyB, info))
|
|
{
|
|
match = true;
|
|
|
|
if (overlapCallback)
|
|
{
|
|
overlapCallback.call(callbackContext, entry, bodyB, info);
|
|
}
|
|
else if (!processCallback)
|
|
{
|
|
// If there are no callbacks we don't need to test every body, just exit when the first is found
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return match;
|
|
},
|
|
|
|
/**
|
|
* Sets the collision filter category of all given Matter Bodies to the given value.
|
|
*
|
|
* This number must be a power of two between 2^0 (= 1) and 2^31.
|
|
*
|
|
* Bodies with different collision groups (see {@link #setCollisionGroup}) will only collide if their collision
|
|
* categories are included in their collision masks (see {@link #setCollidesWith}).
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setCollisionCategory
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} value - Unique category bitfield.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setCollisionCategory: function (bodies, value)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
body.collisionFilter.category = value;
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the collision filter group of all given Matter Bodies to the given value.
|
|
*
|
|
* If the group value is zero, or if two Matter Bodies have different group values,
|
|
* they will collide according to the usual collision filter rules (see {@link #setCollisionCategory} and {@link #setCollisionGroup}).
|
|
*
|
|
* If two Matter Bodies have the same positive group value, they will always collide;
|
|
* if they have the same negative group value they will never collide.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setCollisionGroup
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} value - Unique group index.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setCollisionGroup: function (bodies, value)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
body.collisionFilter.group = value;
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the collision filter mask of all given Matter Bodies to the given value.
|
|
*
|
|
* Two Matter Bodies with different collision groups will only collide if each one includes the others
|
|
* category in its mask based on a bitwise AND operation: `(categoryA & maskB) !== 0` and
|
|
* `(categoryB & maskA) !== 0` are both true.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setCollidesWith
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody[]} bodies - An array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {(number|number[])} categories - A unique category bitfield, or an array of them.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setCollidesWith: function (bodies, categories)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var flags = 0;
|
|
|
|
if (!Array.isArray(categories))
|
|
{
|
|
flags = categories;
|
|
}
|
|
else
|
|
{
|
|
for (var i = 0; i < categories.length; i++)
|
|
{
|
|
flags |= categories[i];
|
|
}
|
|
}
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
body.collisionFilter.mask = flags;
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Takes an array and returns a new array made from all of the Matter Bodies found in the original array.
|
|
*
|
|
* For example, passing in Matter Game Objects, such as a bunch of Matter Sprites, to this method, would
|
|
* return an array containing all of their native Matter Body objects.
|
|
*
|
|
* If the `bodies` argument is falsey, it will return all bodies in the world.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#getMatterBodies
|
|
* @since 3.22.0
|
|
*
|
|
* @param {array} [bodies] - An array of objects to extract the bodies from. If falsey, it will return all bodies in the world.
|
|
*
|
|
* @return {MatterJS.BodyType[]} An array of native Matter Body objects.
|
|
*/
|
|
getMatterBodies: function (bodies)
|
|
{
|
|
if (!bodies)
|
|
{
|
|
return this.world.getAllBodies();
|
|
}
|
|
|
|
if (!Array.isArray(bodies))
|
|
{
|
|
bodies = [ bodies ];
|
|
}
|
|
|
|
var output = [];
|
|
|
|
for (var i = 0; i < bodies.length; i++)
|
|
{
|
|
var body = (bodies[i].hasOwnProperty('body')) ? bodies[i].body : bodies[i];
|
|
|
|
output.push(body);
|
|
}
|
|
|
|
return output;
|
|
},
|
|
|
|
/**
|
|
* Sets both the horizontal and vertical linear velocity of the physics bodies.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setVelocity
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} x - The horizontal linear velocity value.
|
|
* @param {number} y - The vertical linear velocity value.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setVelocity: function (bodies, x, y)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var vec2 = this._tempVec2;
|
|
|
|
vec2.x = x;
|
|
vec2.y = y;
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
Body.setVelocity(body, vec2);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets just the horizontal linear velocity of the physics bodies.
|
|
* The vertical velocity of the body is unchanged.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setVelocityX
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} x - The horizontal linear velocity value.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setVelocityX: function (bodies, x)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var vec2 = this._tempVec2;
|
|
|
|
vec2.x = x;
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
vec2.y = body.velocity.y;
|
|
Body.setVelocity(body, vec2);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets just the vertical linear velocity of the physics bodies.
|
|
* The horizontal velocity of the body is unchanged.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setVelocityY
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} y - The vertical linear velocity value.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setVelocityY: function (bodies, y)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var vec2 = this._tempVec2;
|
|
|
|
vec2.y = y;
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
vec2.x = body.velocity.x;
|
|
Body.setVelocity(body, vec2);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Sets the angular velocity of the bodies instantly.
|
|
* Position, angle, force etc. are unchanged.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#setAngularVelocity
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} value - The angular velocity.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
setAngularVelocity: function (bodies, value)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
Body.setAngularVelocity(body, value);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Applies a force to a body, at the bodies current position, including resulting torque.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#applyForce
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {Phaser.Types.Math.Vector2Like} force - A Vector that specifies the force to apply.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
applyForce: function (bodies, force)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var vec2 = this._tempVec2;
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
vec2.x = body.position.x;
|
|
vec2.y = body.position.y;
|
|
|
|
Body.applyForce(body, vec2, force);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Applies a force to a body, from the given world position, including resulting torque.
|
|
* If no angle is given, the current body angle is used.
|
|
*
|
|
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromPosition
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {Phaser.Types.Math.Vector2Like} position - A Vector that specifies the world-space position to apply the force at.
|
|
* @param {number} speed - A speed value to be applied to a directional force.
|
|
* @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
applyForceFromPosition: function (bodies, position, speed, angle)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var vec2 = this._tempVec2;
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
if (angle === undefined)
|
|
{
|
|
angle = body.angle;
|
|
}
|
|
|
|
vec2.x = speed * Math.cos(angle);
|
|
vec2.y = speed * Math.sin(angle);
|
|
|
|
Body.applyForce(body, position, vec2);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Apply a force to a body based on the given angle and speed.
|
|
* If no angle is given, the current body angle is used.
|
|
*
|
|
* Use very small speed values, such as 0.1, depending on the mass and required velocity.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#applyForceFromAngle
|
|
* @since 3.22.0
|
|
*
|
|
* @param {(Phaser.Types.Physics.Matter.MatterBody|Phaser.Types.Physics.Matter.MatterBody[])} bodies - Either a single Body, or an array of bodies to update. If falsey it will use all bodies in the world.
|
|
* @param {number} speed - A speed value to be applied to a directional force.
|
|
* @param {number} [angle] - The angle, in radians, to apply the force from. Leave undefined to use the current body angle.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
applyForceFromAngle: function (bodies, speed, angle)
|
|
{
|
|
bodies = this.getMatterBodies(bodies);
|
|
|
|
var vec2 = this._tempVec2;
|
|
|
|
bodies.forEach(function (body)
|
|
{
|
|
if (angle === undefined)
|
|
{
|
|
angle = body.angle;
|
|
}
|
|
|
|
vec2.x = speed * Math.cos(angle);
|
|
vec2.y = speed * Math.sin(angle);
|
|
|
|
Body.applyForce(body, { x: body.position.x, y: body.position.y }, vec2);
|
|
});
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* Returns the length of the given constraint, which is the distance between the two points.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#getConstraintLength
|
|
* @since 3.22.0
|
|
*
|
|
* @param {MatterJS.ConstraintType} constraint - The constraint to get the length from.
|
|
*
|
|
* @return {number} The length of the constraint.
|
|
*/
|
|
getConstraintLength: function (constraint)
|
|
{
|
|
var aX = constraint.pointA.x;
|
|
var aY = constraint.pointA.y;
|
|
var bX = constraint.pointB.x;
|
|
var bY = constraint.pointB.y;
|
|
|
|
if (constraint.bodyA)
|
|
{
|
|
aX += constraint.bodyA.position.x;
|
|
aY += constraint.bodyA.position.y;
|
|
}
|
|
|
|
if (constraint.bodyB)
|
|
{
|
|
bX += constraint.bodyB.position.x;
|
|
bY += constraint.bodyB.position.y;
|
|
}
|
|
|
|
return DistanceBetween(aX, aY, bX, bY);
|
|
},
|
|
|
|
/**
|
|
* Aligns a Body, or Matter Game Object, against the given coordinates.
|
|
*
|
|
* The alignment takes place using the body bounds, which take into consideration things
|
|
* like body scale and rotation.
|
|
*
|
|
* Although a Body has a `position` property, it is based on the center of mass for the body,
|
|
* not a dimension based center. This makes aligning bodies difficult, especially if they have
|
|
* rotated or scaled. This method will derive the correct position based on the body bounds and
|
|
* its center of mass offset, in order to align the body with the given coordinate.
|
|
*
|
|
* For example, if you wanted to align a body so it sat in the bottom-center of the
|
|
* Scene, and the world was 800 x 600 in size:
|
|
*
|
|
* ```javascript
|
|
* this.matter.alignBody(body, 400, 600, Phaser.Display.Align.BOTTOM_CENTER);
|
|
* ```
|
|
*
|
|
* You pass in 400 for the x coordinate, because that is the center of the world, and 600 for
|
|
* the y coordinate, as that is the base of the world.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#alignBody
|
|
* @since 3.22.0
|
|
*
|
|
* @param {Phaser.Types.Physics.Matter.MatterBody} body - The Body to align.
|
|
* @param {number} x - The horizontal position to align the body to.
|
|
* @param {number} y - The vertical position to align the body to.
|
|
* @param {number} align - One of the `Phaser.Display.Align` constants, such as `Phaser.Display.Align.TOP_LEFT`.
|
|
*
|
|
* @return {this} This Matter Physics instance.
|
|
*/
|
|
alignBody: function (body, x, y, align)
|
|
{
|
|
body = (body.hasOwnProperty('body')) ? body.body : body;
|
|
|
|
var pos;
|
|
|
|
switch (align)
|
|
{
|
|
case ALIGN_CONST.TOP_LEFT:
|
|
case ALIGN_CONST.LEFT_TOP:
|
|
pos = this.bodyBounds.getTopLeft(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.TOP_CENTER:
|
|
pos = this.bodyBounds.getTopCenter(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.TOP_RIGHT:
|
|
case ALIGN_CONST.RIGHT_TOP:
|
|
pos = this.bodyBounds.getTopRight(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.LEFT_CENTER:
|
|
pos = this.bodyBounds.getLeftCenter(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.CENTER:
|
|
pos = this.bodyBounds.getCenter(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.RIGHT_CENTER:
|
|
pos = this.bodyBounds.getRightCenter(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.LEFT_BOTTOM:
|
|
case ALIGN_CONST.BOTTOM_LEFT:
|
|
pos = this.bodyBounds.getBottomLeft(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.BOTTOM_CENTER:
|
|
pos = this.bodyBounds.getBottomCenter(body, x, y);
|
|
break;
|
|
|
|
case ALIGN_CONST.BOTTOM_RIGHT:
|
|
case ALIGN_CONST.RIGHT_BOTTOM:
|
|
pos = this.bodyBounds.getBottomRight(body, x, y);
|
|
break;
|
|
}
|
|
|
|
if (pos)
|
|
{
|
|
Body.setPosition(body, pos);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
|
|
/**
|
|
* The Scene that owns this plugin is shutting down.
|
|
* We need to kill and reset all internal properties as well as stop listening to Scene events.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#shutdown
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
shutdown: function ()
|
|
{
|
|
var eventEmitter = this.systems.events;
|
|
|
|
if (this.world)
|
|
{
|
|
eventEmitter.off(SceneEvents.UPDATE, this.world.update, this.world);
|
|
eventEmitter.off(SceneEvents.POST_UPDATE, this.world.postUpdate, this.world);
|
|
}
|
|
|
|
eventEmitter.off(SceneEvents.SHUTDOWN, this.shutdown, this);
|
|
|
|
if (this.add)
|
|
{
|
|
this.add.destroy();
|
|
}
|
|
|
|
if (this.world)
|
|
{
|
|
this.world.destroy();
|
|
}
|
|
|
|
this.add = null;
|
|
this.world = null;
|
|
},
|
|
|
|
/**
|
|
* The Scene that owns this plugin is being destroyed.
|
|
* We need to shutdown and then kill off all external references.
|
|
*
|
|
* @method Phaser.Physics.Matter.MatterPhysics#destroy
|
|
* @private
|
|
* @since 3.0.0
|
|
*/
|
|
destroy: function ()
|
|
{
|
|
this.shutdown();
|
|
|
|
this.scene.sys.events.off(SceneEvents.START, this.start, this);
|
|
|
|
this.scene = null;
|
|
this.systems = null;
|
|
}
|
|
|
|
});
|
|
|
|
PluginCache.register('MatterPhysics', MatterPhysics, 'matterPhysics');
|
|
|
|
module.exports = MatterPhysics;
|