2018-02-12 16:01:20 +00:00
|
|
|
/**
|
|
|
|
* @author Richard Davey <rich@photonstorm.com>
|
2019-01-15 16:20:22 +00:00
|
|
|
* @copyright 2019 Photon Storm Ltd.
|
2019-05-10 15:15:04 +00:00
|
|
|
* @license {@link https://opensource.org/licenses/MIT|MIT License}
|
2018-02-12 16:01:20 +00:00
|
|
|
*/
|
|
|
|
|
2017-11-21 16:54:54 +00:00
|
|
|
var Bodies = require('./lib/factory/Bodies');
|
2019-04-08 09:34:38 +00:00
|
|
|
var Body = require('./lib/body/Body');
|
2017-11-20 16:54:26 +00:00
|
|
|
var Class = require('../../utils/Class');
|
2018-04-03 14:30:46 +00:00
|
|
|
var Common = require('./lib/core/Common');
|
2017-11-27 03:45:46 +00:00
|
|
|
var Composite = require('./lib/body/Composite');
|
2017-11-21 16:54:54 +00:00
|
|
|
var Engine = require('./lib/core/Engine');
|
2018-01-12 17:09:09 +00:00
|
|
|
var EventEmitter = require('eventemitter3');
|
2019-01-17 15:47:27 +00:00
|
|
|
var Events = require('./events');
|
2017-11-21 16:54:54 +00:00
|
|
|
var GetFastValue = require('../../utils/object/GetFastValue');
|
2017-11-22 02:25:30 +00:00
|
|
|
var GetValue = require('../../utils/object/GetValue');
|
|
|
|
var MatterBody = require('./lib/body/Body');
|
|
|
|
var MatterEvents = require('./lib/core/Events');
|
2018-01-21 18:53:48 +00:00
|
|
|
var MatterTileBody = require('./MatterTileBody');
|
2018-04-03 14:30:46 +00:00
|
|
|
var MatterWorld = require('./lib/body/World');
|
2018-03-26 03:44:32 +00:00
|
|
|
var Vector = require('./lib/geometry/Vector');
|
2017-11-20 16:54:26 +00:00
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* @classdesc
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @class World
|
2018-03-28 14:04:09 +00:00
|
|
|
* @extends Phaser.Events.EventEmitter
|
2018-10-10 09:49:13 +00:00
|
|
|
* @memberof Phaser.Physics.Matter
|
2018-02-12 13:48:38 +00:00
|
|
|
* @constructor
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-09-28 11:19:21 +00:00
|
|
|
* @param {Phaser.Scene} scene - The Scene to which this Matter World instance belongs.
|
2019-05-09 14:31:59 +00:00
|
|
|
* @param {Phaser.Types.Physics.Matter.MatterWorldConfig} config - The Matter World configuration object.
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-20 16:54:26 +00:00
|
|
|
var World = new Class({
|
|
|
|
|
2018-01-12 18:59:11 +00:00
|
|
|
Extends: EventEmitter,
|
|
|
|
|
2017-11-20 16:54:26 +00:00
|
|
|
initialize:
|
|
|
|
|
|
|
|
function World (scene, config)
|
|
|
|
{
|
2018-01-12 18:59:11 +00:00
|
|
|
EventEmitter.call(this);
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* The Scene to which this Matter World instance belongs.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#scene
|
|
|
|
* @type {Phaser.Scene}
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-20 16:54:26 +00:00
|
|
|
this.scene = scene;
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* An instance of the MatterJS Engine.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#engine
|
2018-03-29 13:24:51 +00:00
|
|
|
* @type {MatterJS.Engine}
|
2018-02-12 13:48:38 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
this.engine = Engine.create(config);
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-03-19 15:01:14 +00:00
|
|
|
* A `World` composite object that will contain all simulated bodies and constraints.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#localWorld
|
2018-03-29 13:24:51 +00:00
|
|
|
* @type {MatterJS.World}
|
2018-02-12 13:48:38 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
this.localWorld = this.engine.world;
|
|
|
|
|
|
|
|
var gravity = GetValue(config, 'gravity', null);
|
|
|
|
|
|
|
|
if (gravity)
|
|
|
|
{
|
|
|
|
this.setGravity(gravity.x, gravity.y, gravity.scale);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-02-12 13:48:38 +00:00
|
|
|
* An object containing the 4 wall bodies that bound the physics world.
|
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#walls
|
2018-03-19 15:01:14 +00:00
|
|
|
* @type {object}
|
2018-02-12 13:48:38 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
this.walls = { left: null, right: null, top: null, bottom: null };
|
2018-01-21 18:53:48 +00:00
|
|
|
|
2017-11-21 16:54:54 +00:00
|
|
|
if (GetFastValue(config, 'setBounds', false))
|
|
|
|
{
|
|
|
|
var boundsConfig = config['setBounds'];
|
|
|
|
|
|
|
|
if (typeof boundsConfig === 'boolean')
|
|
|
|
{
|
|
|
|
this.setBounds();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
var x = GetFastValue(boundsConfig, 'x', 0);
|
|
|
|
var y = GetFastValue(boundsConfig, 'y', 0);
|
2019-01-11 15:57:57 +00:00
|
|
|
var width = GetFastValue(boundsConfig, 'width', scene.sys.scale.width);
|
|
|
|
var height = GetFastValue(boundsConfig, 'height', scene.sys.scale.height);
|
2017-11-21 16:54:54 +00:00
|
|
|
var thickness = GetFastValue(boundsConfig, 'thickness', 64);
|
|
|
|
var left = GetFastValue(boundsConfig, 'left', true);
|
|
|
|
var right = GetFastValue(boundsConfig, 'right', true);
|
|
|
|
var top = GetFastValue(boundsConfig, 'top', true);
|
|
|
|
var bottom = GetFastValue(boundsConfig, 'bottom', true);
|
|
|
|
|
|
|
|
this.setBounds(x, y, width, height, thickness, left, right, top, bottom);
|
|
|
|
}
|
|
|
|
}
|
2017-11-22 02:25:30 +00:00
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* A flag that toggles if the world is enabled or not.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#enabled
|
|
|
|
* @type {boolean}
|
|
|
|
* @default true
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
|
|
|
this.enabled = GetValue(config, 'enabled', true);
|
2017-11-27 03:45:46 +00:00
|
|
|
|
2018-03-23 02:19:18 +00:00
|
|
|
/**
|
|
|
|
* The correction argument is an optional Number that specifies the time correction factor to apply to the update.
|
|
|
|
* This can help improve the accuracy of the simulation in cases where delta is changing between updates.
|
|
|
|
* The value of correction is defined as delta / lastDelta, i.e. the percentage change of delta over the last step.
|
|
|
|
* Therefore the value is always 1 (no correction) when delta constant (or when no correction is desired, which is the default).
|
|
|
|
* See the paper on Time Corrected Verlet for more information.
|
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#correction
|
|
|
|
* @type {number}
|
|
|
|
* @default 1
|
2018-03-27 14:15:05 +00:00
|
|
|
* @since 3.4.0
|
2018-03-23 02:19:18 +00:00
|
|
|
*/
|
|
|
|
this.correction = GetValue(config, 'correction', 1);
|
|
|
|
|
2018-03-27 14:15:05 +00:00
|
|
|
/**
|
|
|
|
* This function is called every time the core game loop steps, which is bound to the
|
|
|
|
* Request Animation Frame frequency unless otherwise modified.
|
|
|
|
*
|
|
|
|
* The function is passed two values: `time` and `delta`, both of which come from the game step values.
|
|
|
|
*
|
|
|
|
* It must return a number. This number is used as the delta value passed to Matter.Engine.update.
|
|
|
|
*
|
|
|
|
* You can override this function with your own to define your own timestep.
|
|
|
|
*
|
|
|
|
* If you need to update the Engine multiple times in a single game step then call
|
|
|
|
* `World.update` as many times as required. Each call will trigger the `getDelta` function.
|
|
|
|
* If you wish to have full control over when the Engine updates then see the property `autoUpdate`.
|
|
|
|
*
|
|
|
|
* You can also adjust the number of iterations that Engine.update performs.
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#getDelta
|
|
|
|
* @type {function}
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
|
|
|
this.getDelta = GetValue(config, 'getDelta', this.update60Hz);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Automatically call Engine.update every time the game steps.
|
|
|
|
* If you disable this then you are responsible for calling `World.step` directly from your game.
|
|
|
|
* If you call `set60Hz` or `set30Hz` then `autoUpdate` is reset to `true`.
|
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#autoUpdate
|
|
|
|
* @type {boolean}
|
|
|
|
* @default true
|
|
|
|
* @since 3.4.0
|
|
|
|
*/
|
|
|
|
this.autoUpdate = GetValue(config, 'autoUpdate', true);
|
|
|
|
|
2019-11-27 17:49:21 +00:00
|
|
|
var debugConfig = GetValue(config, 'debug', false);
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* A flag that controls if the debug graphics will be drawn to or not.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#drawDebug
|
|
|
|
* @type {boolean}
|
|
|
|
* @default false
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2019-11-27 17:49:21 +00:00
|
|
|
this.drawDebug = (!debugConfig) ? false : true;
|
2017-11-27 03:45:46 +00:00
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* An instance of the Graphics object the debug bodies are drawn to, if enabled.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @name Phaser.Physics.Matter.World#debugGraphic
|
|
|
|
* @type {Phaser.GameObjects.Graphics}
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-27 03:45:46 +00:00
|
|
|
this.debugGraphic;
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* The default configuration values.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
2019-11-26 16:39:34 +00:00
|
|
|
* @name Phaser.Physics.Matter.World#debugConfig
|
2018-02-12 13:48:38 +00:00
|
|
|
* @type {object}
|
2019-11-26 16:39:34 +00:00
|
|
|
* @since 3.22.0
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2019-11-26 16:39:34 +00:00
|
|
|
this.debugConfig = {
|
2019-11-27 17:49:21 +00:00
|
|
|
showBody: GetFastValue(debugConfig, 'showBody', true),
|
|
|
|
showStaticBody: GetFastValue(debugConfig, 'showStaticBody', true),
|
|
|
|
showSleeping: GetFastValue(debugConfig, 'showSleeping', false),
|
|
|
|
showJoint: GetFastValue(debugConfig, 'showJoint', true),
|
|
|
|
showInternalEdges: GetFastValue(debugConfig, 'showInternalEdges', false),
|
|
|
|
showConvexHulls: GetFastValue(debugConfig, 'showConvexHulls', false),
|
|
|
|
|
|
|
|
renderFill: GetFastValue(debugConfig, 'renderFill', true),
|
|
|
|
renderStroke: GetFastValue(debugConfig, 'renderStroke', true),
|
|
|
|
|
|
|
|
fillColor: GetFastValue(debugConfig, 'fillColor', 0x106909),
|
|
|
|
strokeColor: GetFastValue(debugConfig, 'strokeColor', 0x28de19),
|
|
|
|
|
|
|
|
staticFillColor: GetFastValue(debugConfig, 'staticFillColor', 0x0d177b),
|
|
|
|
staticStrokeColor: GetFastValue(debugConfig, 'staticStrokeColor', 0x1327e4),
|
|
|
|
|
|
|
|
staticBodySleepOpacity: GetFastValue(debugConfig, 'staticBodySleepOpacity', 0.7),
|
|
|
|
sleepFillColor: GetFastValue(debugConfig, 'sleepFillColor', 0x464646),
|
|
|
|
sleepStrokeColor: GetFastValue(debugConfig, 'sleepStrokeColor', 0x999a99),
|
|
|
|
|
|
|
|
jointColor: GetFastValue(debugConfig, 'jointColor', 0xe0e042),
|
|
|
|
jointLineThickness: GetFastValue(debugConfig, 'jointLineThickness', 2),
|
|
|
|
|
|
|
|
pinSize: GetFastValue(debugConfig, 'pinSize', 4),
|
|
|
|
pinColor: GetFastValue(debugConfig, 'pinColor', 0x42e0e0),
|
|
|
|
|
|
|
|
springColor: GetFastValue(debugConfig, 'springColor', 0xe042e0),
|
|
|
|
|
|
|
|
anchorColor: GetFastValue(debugConfig, 'anchorColor', 0xefefef),
|
|
|
|
anchorSize: GetFastValue(debugConfig, 'anchorSize', 6),
|
|
|
|
|
|
|
|
hullColor: GetFastValue(debugConfig, 'hullColor', 0xd703d0)
|
2017-11-27 03:45:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (this.drawDebug)
|
|
|
|
{
|
|
|
|
this.createDebugGraphic();
|
|
|
|
}
|
|
|
|
|
2018-04-13 16:43:56 +00:00
|
|
|
this.setEventsProxy();
|
2017-11-22 02:25:30 +00:00
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#setEventsProxy
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-22 02:25:30 +00:00
|
|
|
setEventsProxy: function ()
|
|
|
|
{
|
2018-01-12 18:59:11 +00:00
|
|
|
var _this = this;
|
|
|
|
var engine = this.engine;
|
2017-11-22 02:25:30 +00:00
|
|
|
|
2018-02-16 18:17:51 +00:00
|
|
|
MatterEvents.on(engine, 'beforeUpdate', function (event)
|
|
|
|
{
|
2019-01-17 15:47:27 +00:00
|
|
|
_this.emit(Events.BEFORE_UPDATE, event);
|
2017-11-23 01:45:38 +00:00
|
|
|
});
|
|
|
|
|
2018-02-16 18:17:51 +00:00
|
|
|
MatterEvents.on(engine, 'afterUpdate', function (event)
|
|
|
|
{
|
2019-01-17 15:47:27 +00:00
|
|
|
_this.emit(Events.AFTER_UPDATE, event);
|
2017-11-23 01:45:38 +00:00
|
|
|
});
|
|
|
|
|
2018-02-16 18:17:51 +00:00
|
|
|
MatterEvents.on(engine, 'collisionStart', function (event)
|
|
|
|
{
|
2018-01-12 18:59:11 +00:00
|
|
|
var pairs = event.pairs;
|
|
|
|
var bodyA;
|
|
|
|
var bodyB;
|
2017-11-22 02:25:30 +00:00
|
|
|
|
2018-01-12 18:59:11 +00:00
|
|
|
if (pairs.length > 0)
|
|
|
|
{
|
|
|
|
bodyA = pairs[0].bodyA;
|
|
|
|
bodyB = pairs[0].bodyB;
|
|
|
|
}
|
|
|
|
|
2019-01-17 15:47:27 +00:00
|
|
|
_this.emit(Events.COLLISION_START, event, bodyA, bodyB);
|
2017-11-22 02:25:30 +00:00
|
|
|
});
|
|
|
|
|
2018-02-16 18:17:51 +00:00
|
|
|
MatterEvents.on(engine, 'collisionActive', function (event)
|
|
|
|
{
|
2018-01-12 18:59:11 +00:00
|
|
|
var pairs = event.pairs;
|
|
|
|
var bodyA;
|
|
|
|
var bodyB;
|
|
|
|
|
|
|
|
if (pairs.length > 0)
|
|
|
|
{
|
|
|
|
bodyA = pairs[0].bodyA;
|
|
|
|
bodyB = pairs[0].bodyB;
|
|
|
|
}
|
|
|
|
|
2019-01-17 15:47:27 +00:00
|
|
|
_this.emit(Events.COLLISION_ACTIVE, event, bodyA, bodyB);
|
2017-11-22 02:25:30 +00:00
|
|
|
});
|
|
|
|
|
2018-02-16 18:17:51 +00:00
|
|
|
MatterEvents.on(engine, 'collisionEnd', function (event)
|
|
|
|
{
|
2018-01-12 18:59:11 +00:00
|
|
|
var pairs = event.pairs;
|
|
|
|
var bodyA;
|
|
|
|
var bodyB;
|
|
|
|
|
|
|
|
if (pairs.length > 0)
|
|
|
|
{
|
|
|
|
bodyA = pairs[0].bodyA;
|
|
|
|
bodyB = pairs[0].bodyB;
|
|
|
|
}
|
2017-11-22 02:25:30 +00:00
|
|
|
|
2019-01-17 15:47:27 +00:00
|
|
|
_this.emit(Events.COLLISION_END, event, bodyA, bodyB);
|
2017-11-22 02:25:30 +00:00
|
|
|
});
|
2017-11-21 16:54:54 +00:00
|
|
|
},
|
2017-11-21 02:04:05 +00:00
|
|
|
|
2017-11-21 16:54:54 +00:00
|
|
|
/**
|
2018-02-12 13:48:38 +00:00
|
|
|
* Sets the bounds of the Physics world to match the given world pixel dimensions.
|
|
|
|
* You can optionally set which 'walls' to create: left, right, top or bottom.
|
|
|
|
* If none of the walls are given it will default to use the walls settings it had previously.
|
|
|
|
* I.e. if you previously told it to not have the left or right walls, and you then adjust the world size
|
|
|
|
* the newly created bounds will also not have the left and right walls.
|
|
|
|
* Explicitly state them in the parameters to override this.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#setBounds
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 00:10:32 +00:00
|
|
|
* @param {number} [x=0] - The x coordinate of the top-left corner of the bounds.
|
|
|
|
* @param {number} [y=0] - The y coordinate of the top-left corner of the bounds.
|
|
|
|
* @param {number} [width] - The width of the bounds.
|
|
|
|
* @param {number} [height] - The height of the bounds.
|
2018-02-12 13:48:38 +00:00
|
|
|
* @param {number} [thickness=128] - The thickness of each wall, in pixels.
|
|
|
|
* @param {boolean} [left=true] - If true will create the left bounds wall.
|
|
|
|
* @param {boolean} [right=true] - If true will create the right bounds wall.
|
|
|
|
* @param {boolean} [top=true] - If true will create the top bounds wall.
|
|
|
|
* @param {boolean} [bottom=true] - If true will create the bottom bounds wall.
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
setBounds: function (x, y, width, height, thickness, left, right, top, bottom)
|
|
|
|
{
|
|
|
|
if (x === undefined) { x = 0; }
|
|
|
|
if (y === undefined) { y = 0; }
|
2019-01-11 15:57:57 +00:00
|
|
|
if (width === undefined) { width = this.scene.sys.scale.width; }
|
|
|
|
if (height === undefined) { height = this.scene.sys.scale.height; }
|
2017-11-23 14:59:15 +00:00
|
|
|
if (thickness === undefined) { thickness = 128; }
|
2017-11-21 16:54:54 +00:00
|
|
|
if (left === undefined) { left = true; }
|
|
|
|
if (right === undefined) { right = true; }
|
|
|
|
if (top === undefined) { top = true; }
|
|
|
|
if (bottom === undefined) { bottom = true; }
|
|
|
|
|
2019-02-09 16:27:20 +00:00
|
|
|
this.updateWall(left, 'left', x - thickness, y - thickness, thickness, height + (thickness * 2));
|
|
|
|
this.updateWall(right, 'right', x + width, y - thickness, thickness, height + (thickness * 2));
|
2017-11-21 16:54:54 +00:00
|
|
|
this.updateWall(top, 'top', x, y - thickness, width, thickness);
|
|
|
|
this.updateWall(bottom, 'bottom', x, y + height, width, thickness);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
2017-11-21 02:04:05 +00:00
|
|
|
|
2017-11-21 16:54:54 +00:00
|
|
|
// position = 'left', 'right', 'top' or 'bottom'
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#updateWall
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 00:10:32 +00:00
|
|
|
* @param {boolean} add - [description]
|
|
|
|
* @param {string} position - [description]
|
|
|
|
* @param {number} x - [description]
|
|
|
|
* @param {number} y - [description]
|
|
|
|
* @param {number} width - [description]
|
|
|
|
* @param {number} height - [description]
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
updateWall: function (add, position, x, y, width, height)
|
|
|
|
{
|
|
|
|
var wall = this.walls[position];
|
|
|
|
|
|
|
|
if (add)
|
|
|
|
{
|
|
|
|
if (wall)
|
|
|
|
{
|
2017-11-29 23:36:35 +00:00
|
|
|
MatterWorld.remove(this.localWorld, wall);
|
2017-11-21 16:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// adjust center
|
|
|
|
x += (width / 2);
|
|
|
|
y += (height / 2);
|
|
|
|
|
2017-11-27 03:45:46 +00:00
|
|
|
this.walls[position] = this.create(x, y, width, height, { isStatic: true, friction: 0, frictionStatic: 0 });
|
2017-11-21 16:54:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (wall)
|
|
|
|
{
|
2017-11-29 23:36:35 +00:00
|
|
|
MatterWorld.remove(this.localWorld, wall);
|
2017-11-21 16:54:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
this.walls[position] = null;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#createDebugGraphic
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @return {Phaser.GameObjects.Graphics} [description]
|
|
|
|
*/
|
2017-11-27 03:45:46 +00:00
|
|
|
createDebugGraphic: function ()
|
|
|
|
{
|
|
|
|
var graphic = this.scene.sys.add.graphics({ x: 0, y: 0 });
|
|
|
|
|
2018-04-03 14:30:46 +00:00
|
|
|
graphic.setDepth(Number.MAX_VALUE);
|
2017-11-27 03:45:46 +00:00
|
|
|
|
|
|
|
this.debugGraphic = graphic;
|
|
|
|
|
|
|
|
this.drawDebug = true;
|
|
|
|
|
|
|
|
return graphic;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-12-03 15:16:23 +00:00
|
|
|
* Sets the world's gravity and gravity scale to 0.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#disableGravity
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
2017-11-27 03:45:46 +00:00
|
|
|
disableGravity: function ()
|
|
|
|
{
|
|
|
|
this.localWorld.gravity.x = 0;
|
|
|
|
this.localWorld.gravity.y = 0;
|
|
|
|
this.localWorld.gravity.scale = 0;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-12-03 15:16:23 +00:00
|
|
|
* Sets the world's gravity
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#setGravity
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-12-03 15:16:23 +00:00
|
|
|
* @param {number} [x=0] - The world gravity x component.
|
|
|
|
* @param {number} [y=1] - The world gravity y component.
|
2018-02-12 13:48:38 +00:00
|
|
|
* @param {number} [scale] - [description]
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
setGravity: function (x, y, scale)
|
|
|
|
{
|
2017-11-27 16:29:33 +00:00
|
|
|
if (x === undefined) { x = 0; }
|
|
|
|
if (y === undefined) { y = 1; }
|
|
|
|
|
2017-11-21 16:54:54 +00:00
|
|
|
this.localWorld.gravity.x = x;
|
|
|
|
this.localWorld.gravity.y = y;
|
|
|
|
|
|
|
|
if (scale !== undefined)
|
|
|
|
{
|
|
|
|
this.localWorld.gravity.scale = scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-28 11:19:21 +00:00
|
|
|
* Creates a rectangle Matter body and adds it to the world.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#create
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-09-28 11:19:21 +00:00
|
|
|
* @param {number} x - The horizontal position of the body in the world.
|
|
|
|
* @param {number} y - The vertical position of the body in the world.
|
|
|
|
* @param {number} width - The width of the body.
|
|
|
|
* @param {number} height - The height of the body.
|
|
|
|
* @param {object} options - Optional Matter configuration object.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
2018-09-28 11:19:21 +00:00
|
|
|
* @return {MatterJS.Body} The Matter.js body that was created.
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-21 16:54:54 +00:00
|
|
|
create: function (x, y, width, height, options)
|
|
|
|
{
|
|
|
|
var body = Bodies.rectangle(x, y, width, height, options);
|
|
|
|
|
|
|
|
MatterWorld.add(this.localWorld, body);
|
|
|
|
|
|
|
|
return body;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-12-03 15:16:23 +00:00
|
|
|
* Adds an object to the world.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#add
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-20 15:10:19 +00:00
|
|
|
* @param {(object|object[])} object - Can be single or an array, and can be a body, composite or constraint
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
2017-11-27 03:45:46 +00:00
|
|
|
add: function (object)
|
2017-11-21 16:54:54 +00:00
|
|
|
{
|
2017-11-27 03:45:46 +00:00
|
|
|
MatterWorld.add(this.localWorld, object);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#remove
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 15:01:14 +00:00
|
|
|
* @param {object} object - The object to be removed from the world.
|
2018-02-12 13:48:38 +00:00
|
|
|
* @param {boolean} deep - [description]
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
2017-11-27 03:45:46 +00:00
|
|
|
remove: function (object, deep)
|
|
|
|
{
|
2017-12-02 04:05:27 +00:00
|
|
|
var body = (object.body) ? object.body : object;
|
|
|
|
|
2019-02-08 19:46:13 +00:00
|
|
|
Composite.remove(this.localWorld, body, deep);
|
2017-11-21 02:04:05 +00:00
|
|
|
|
2017-11-21 16:54:54 +00:00
|
|
|
return this;
|
2017-11-20 16:54:26 +00:00
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#removeConstraint
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-29 13:24:51 +00:00
|
|
|
* @param {MatterJS.Constraint} constraint - [description]
|
2018-02-12 13:48:38 +00:00
|
|
|
* @param {boolean} deep - [description]
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
2018-02-12 13:37:29 +00:00
|
|
|
removeConstraint: function (constraint, deep)
|
|
|
|
{
|
|
|
|
Composite.remove(this.localWorld, constraint, deep);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-01-21 18:53:48 +00:00
|
|
|
/**
|
2018-01-25 20:04:58 +00:00
|
|
|
* Adds MatterTileBody instances for all the colliding tiles within the given tilemap layer. Set
|
|
|
|
* the appropriate tiles in your layer to collide before calling this method!
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#convertTilemapLayer
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-28 14:39:57 +00:00
|
|
|
* @param {(Phaser.Tilemaps.DynamicTilemapLayer|Phaser.Tilemaps.StaticTilemapLayer)} tilemapLayer -
|
2018-01-25 20:04:58 +00:00
|
|
|
* An array of tiles.
|
2018-03-19 00:10:32 +00:00
|
|
|
* @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@ee Phaser.Physics.Matter.TileBody}
|
|
|
|
*
|
2018-02-12 13:48:38 +00:00
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
2018-01-21 18:53:48 +00:00
|
|
|
*/
|
|
|
|
convertTilemapLayer: function (tilemapLayer, options)
|
|
|
|
{
|
|
|
|
var layerData = tilemapLayer.layer;
|
2019-01-08 11:50:21 +00:00
|
|
|
var tiles = tilemapLayer.getTilesWithin(0, 0, layerData.width, layerData.height, { isColliding: true });
|
2018-01-21 18:53:48 +00:00
|
|
|
|
|
|
|
this.convertTiles(tiles, options);
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
2018-01-25 20:04:58 +00:00
|
|
|
* Adds MatterTileBody instances for the given tiles. This adds bodies regardless of whether the
|
|
|
|
* tiles are set to collide or not.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#convertTiles
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-28 14:39:57 +00:00
|
|
|
* @param {Phaser.Tilemaps.Tile[]} tiles - An array of tiles.
|
2018-03-19 00:10:32 +00:00
|
|
|
* @param {object} [options] - Options to be passed to the MatterTileBody constructor. {@see Phaser.Physics.Matter.TileBody}
|
|
|
|
*
|
2018-02-12 13:48:38 +00:00
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
2018-01-21 18:53:48 +00:00
|
|
|
*/
|
|
|
|
convertTiles: function (tiles, options)
|
|
|
|
{
|
|
|
|
if (tiles.length === 0)
|
|
|
|
{
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < tiles.length; i++)
|
|
|
|
{
|
|
|
|
new MatterTileBody(this, tiles[i], options);
|
|
|
|
}
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#nextGroup
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 00:10:32 +00:00
|
|
|
* @param {boolean} isNonColliding - [description]
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
2018-03-19 00:10:32 +00:00
|
|
|
* @return {number} [description]
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-22 02:25:30 +00:00
|
|
|
nextGroup: function (isNonColliding)
|
|
|
|
{
|
2017-11-27 16:29:33 +00:00
|
|
|
return MatterBody.nextGroup(isNonColliding);
|
2017-11-22 02:25:30 +00:00
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#nextCategory
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-12-03 15:16:23 +00:00
|
|
|
* @return {number} Returns the next unique category bitfield.
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-22 02:25:30 +00:00
|
|
|
nextCategory: function ()
|
|
|
|
{
|
|
|
|
return MatterBody.nextCategory();
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#pause
|
2019-01-17 15:47:27 +00:00
|
|
|
* @fires Phaser.Physics.Matter.Events#PAUSE
|
2018-02-12 13:48:38 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
|
|
|
pause: function ()
|
|
|
|
{
|
|
|
|
this.enabled = false;
|
|
|
|
|
2019-01-17 15:47:27 +00:00
|
|
|
this.emit(Events.PAUSE);
|
2018-02-12 13:48:38 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#resume
|
2019-01-17 15:47:27 +00:00
|
|
|
* @fires Phaser.Physics.Matter.Events#RESUME
|
2018-02-12 13:48:38 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*
|
|
|
|
* @return {Phaser.Physics.Matter.World} This Matter World object.
|
|
|
|
*/
|
|
|
|
resume: function ()
|
|
|
|
{
|
|
|
|
this.enabled = true;
|
|
|
|
|
2019-01-17 15:47:27 +00:00
|
|
|
this.emit(Events.RESUME);
|
2018-02-12 13:48:38 +00:00
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#update
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-09-13 07:09:44 +00:00
|
|
|
* @param {number} time - The current time. Either a High Resolution Timer value if it comes from Request Animation Frame, or Date.now if using SetTimeout.
|
|
|
|
* @param {number} delta - The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate.
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-20 16:54:26 +00:00
|
|
|
update: function (time, delta)
|
|
|
|
{
|
2018-03-27 14:15:05 +00:00
|
|
|
if (this.enabled && this.autoUpdate)
|
2017-11-27 03:45:46 +00:00
|
|
|
{
|
2018-03-27 14:15:05 +00:00
|
|
|
Engine.update(this.engine, this.getDelta(time, delta), this.correction);
|
2018-02-12 13:48:38 +00:00
|
|
|
}
|
2017-11-21 02:04:05 +00:00
|
|
|
},
|
|
|
|
|
2018-03-27 14:15:05 +00:00
|
|
|
/**
|
|
|
|
* 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.World#step
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
|
|
|
* @param {number} [delta=16.666] - [description]
|
|
|
|
* @param {number} [correction=1] - [description]
|
|
|
|
*/
|
|
|
|
step: function (delta, correction)
|
|
|
|
{
|
|
|
|
Engine.update(this.engine, delta, correction);
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs the Matter Engine.update at a fixed timestep of 60Hz.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#update60Hz
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
|
|
|
* @return {number} The delta value to be passed to Engine.update.
|
|
|
|
*/
|
|
|
|
update60Hz: function ()
|
|
|
|
{
|
|
|
|
return 1000 / 60;
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Runs the Matter Engine.update at a fixed timestep of 30Hz.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#update30Hz
|
|
|
|
* @since 3.4.0
|
|
|
|
*
|
|
|
|
* @return {number} The delta value to be passed to Engine.update.
|
|
|
|
*/
|
|
|
|
update30Hz: function ()
|
|
|
|
{
|
|
|
|
return 1000 / 30;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-09-26 13:12:20 +00:00
|
|
|
* Handles the rendering of bodies and debug information to the debug Graphics object, if enabled.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#postUpdate
|
2018-09-26 13:12:20 +00:00
|
|
|
* @private
|
2018-02-12 13:48:38 +00:00
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-21 02:04:05 +00:00
|
|
|
postUpdate: function ()
|
|
|
|
{
|
2019-11-26 16:39:34 +00:00
|
|
|
var config = this.debugConfig;
|
|
|
|
|
|
|
|
var showBody = config.showBody;
|
|
|
|
var showStaticBody = config.showStaticBody;
|
|
|
|
var showJoint = config.showJoint;
|
|
|
|
|
|
|
|
if (!this.drawDebug || (!showBody && !showStaticBody && !showJoint))
|
2017-11-27 03:45:46 +00:00
|
|
|
{
|
2018-01-17 15:22:16 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-11-27 03:45:46 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
this.debugGraphic.clear();
|
|
|
|
|
2018-01-17 15:22:16 +00:00
|
|
|
var bodies = Composite.allBodies(this.localWorld);
|
2017-11-27 17:01:27 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
this.renderBodies(bodies);
|
2018-09-26 13:12:20 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
if (showJoint)
|
2018-09-26 13:12:20 +00:00
|
|
|
{
|
2019-11-27 17:49:21 +00:00
|
|
|
this.renderJoints();
|
2018-09-26 13:12:20 +00:00
|
|
|
}
|
|
|
|
},
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
/**
|
|
|
|
* Renders the array of bodies.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#renderBodies
|
|
|
|
* @private
|
|
|
|
* @since 3.14.0
|
|
|
|
*
|
|
|
|
* @param {array} bodies - An array of bodies from the localWorld.
|
|
|
|
*/
|
|
|
|
renderBodies: function (bodies)
|
|
|
|
{
|
|
|
|
var graphics = this.debugGraphic;
|
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
var config = this.debugConfig;
|
|
|
|
|
|
|
|
var showBody = config.showBody;
|
|
|
|
var showStaticBody = config.showStaticBody;
|
|
|
|
var showSleeping = config.showSleeping;
|
|
|
|
var showInternalEdges = config.showInternalEdges;
|
|
|
|
var showConvexHulls = config.showConvexHulls;
|
|
|
|
|
|
|
|
var renderFill = config.renderFill;
|
|
|
|
var renderStroke = config.renderStroke;
|
|
|
|
|
|
|
|
var fillColor = config.fillColor;
|
|
|
|
var strokeColor = config.strokeColor;
|
2019-11-27 17:49:21 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
var staticFillColor = config.staticFillColor;
|
|
|
|
var staticStrokeColor = config.staticStrokeColor;
|
2019-11-27 17:49:21 +00:00
|
|
|
|
|
|
|
var staticBodySleepOpacity = config.staticBodySleepOpacity;
|
|
|
|
var sleepFillColor = config.sleepFillColor;
|
|
|
|
var sleepStrokeColor = config.sleepStrokeColor;
|
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
var hullColor = config.hullColor;
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
var body;
|
|
|
|
var part;
|
2019-11-26 16:39:34 +00:00
|
|
|
var render;
|
2018-09-26 13:12:20 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
for (var i = 0; i < bodies.length; i++)
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
2018-09-26 13:12:20 +00:00
|
|
|
body = bodies[i];
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
// 1) Don't show invisible bodies
|
2018-09-26 13:12:20 +00:00
|
|
|
if (!body.render.visible)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2018-04-03 14:28:51 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
// 2) Don't show static bodies, OR
|
|
|
|
// 3) Don't show dynamic bodies
|
|
|
|
if ((!showStaticBody && body.isStatic) || (!showBody && !body.isStatic))
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
// Handle compound parts
|
2019-11-26 16:39:34 +00:00
|
|
|
var partsLength = body.parts.length;
|
|
|
|
|
|
|
|
for (var k = (partsLength > 1) ? 1 : 0; k < partsLength; k++)
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
2018-09-26 13:12:20 +00:00
|
|
|
part = body.parts[k];
|
2019-11-26 16:39:34 +00:00
|
|
|
render = part.render;
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
if (!render.visible)
|
2018-04-03 14:28:51 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
var opacity = render.opacity;
|
|
|
|
|
2019-11-27 17:49:21 +00:00
|
|
|
var lineStyle = strokeColor;
|
|
|
|
var fillStyle = fillColor;
|
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
if (showSleeping && body.isSleeping)
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
2019-11-27 17:49:21 +00:00
|
|
|
if (body.isStatic)
|
|
|
|
{
|
|
|
|
opacity *= staticBodySleepOpacity;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
lineStyle = sleepStrokeColor;
|
|
|
|
fillStyle = sleepFillColor;
|
|
|
|
}
|
2019-11-26 16:39:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (body.isStatic)
|
|
|
|
{
|
2019-11-27 17:49:21 +00:00
|
|
|
lineStyle = staticStrokeColor;
|
|
|
|
fillStyle = staticFillColor;
|
2018-03-26 03:44:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-27 17:49:21 +00:00
|
|
|
graphics.lineStyle(1, lineStyle, opacity);
|
|
|
|
graphics.fillStyle(fillStyle, opacity);
|
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
// Part polygon
|
|
|
|
if (part.circleRadius)
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
|
|
|
graphics.beginPath();
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.arc(part.position.x, part.position.y, part.circleRadius, 0, 2 * Math.PI);
|
2018-03-26 03:44:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
graphics.beginPath();
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.moveTo(part.vertices[0].x, part.vertices[0].y);
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
var vertLength = part.vertices.length;
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
for (var j = 1; j < vertLength; j++)
|
|
|
|
{
|
|
|
|
if (!part.vertices[j - 1].isInternal || showInternalEdges)
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.lineTo(part.vertices[j].x, part.vertices[j].y);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
graphics.moveTo(part.vertices[j].x, part.vertices[j].y);
|
|
|
|
}
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
if (part.vertices[j].isInternal && !showInternalEdges)
|
|
|
|
{
|
|
|
|
graphics.moveTo(part.vertices[(j + 1) % part.vertices.length].x, part.vertices[(j + 1) % part.vertices.length].y);
|
2018-03-26 03:44:32 +00:00
|
|
|
}
|
|
|
|
}
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
graphics.lineTo(part.vertices[0].x, part.vertices[0].y);
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.closePath();
|
2018-03-26 03:44:32 +00:00
|
|
|
}
|
|
|
|
|
2019-11-26 16:39:34 +00:00
|
|
|
if (renderFill)
|
2018-09-26 13:12:20 +00:00
|
|
|
{
|
|
|
|
graphics.fillPath();
|
|
|
|
}
|
2019-11-26 16:39:34 +00:00
|
|
|
|
|
|
|
if (renderStroke)
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
|
|
|
graphics.strokePath();
|
|
|
|
}
|
2018-09-26 13:12:20 +00:00
|
|
|
}
|
2019-11-26 16:39:34 +00:00
|
|
|
|
|
|
|
// Render Convex Hulls
|
|
|
|
if (showConvexHulls && partsLength > 1)
|
|
|
|
{
|
|
|
|
var verts = body.vertices;
|
|
|
|
|
|
|
|
graphics.lineStyle(1, hullColor);
|
|
|
|
|
|
|
|
graphics.beginPath();
|
|
|
|
|
|
|
|
graphics.moveTo(verts[0].x, verts[0].y);
|
|
|
|
|
|
|
|
for (var v = 1; v < verts.length; v++)
|
|
|
|
{
|
|
|
|
graphics.lineTo(verts[v].x, verts[v].y);
|
|
|
|
}
|
|
|
|
|
|
|
|
graphics.lineTo(verts[0].x, verts[0].y);
|
|
|
|
|
|
|
|
graphics.strokePath();
|
|
|
|
}
|
2018-09-26 13:12:20 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Renders world constraints.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#renderJoints
|
|
|
|
* @private
|
|
|
|
* @since 3.14.0
|
|
|
|
*/
|
|
|
|
renderJoints: function ()
|
|
|
|
{
|
|
|
|
var graphics = this.debugGraphic;
|
2019-11-27 17:49:21 +00:00
|
|
|
var config = this.debugConfig;
|
2018-09-26 13:12:20 +00:00
|
|
|
|
2019-11-27 17:49:21 +00:00
|
|
|
var jointColor = config.jointColor;
|
|
|
|
var jointLineThickness = config.jointLineThickness;
|
|
|
|
var pinSize = config.pinSize;
|
|
|
|
var pinColor = config.pinColor;
|
|
|
|
var springColor = config.springColor;
|
|
|
|
var anchorColor = config.anchorColor;
|
|
|
|
var anchorSize = config.anchorSize;
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
// Render constraints
|
|
|
|
var constraints = Composite.allConstraints(this.localWorld);
|
|
|
|
|
|
|
|
for (var i = 0; i < constraints.length; i++)
|
|
|
|
{
|
|
|
|
var constraint = constraints[i];
|
|
|
|
|
|
|
|
if (!constraint.render.visible || !constraint.pointA || !constraint.pointB)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2019-11-27 17:49:21 +00:00
|
|
|
var custom = constraint.render.custom;
|
|
|
|
|
|
|
|
if (custom)
|
2018-09-26 13:12:20 +00:00
|
|
|
{
|
|
|
|
graphics.lineStyle(constraint.render.lineWidth, Common.colorToNumber(constraint.render.strokeStyle));
|
|
|
|
}
|
2019-11-27 17:49:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
graphics.lineStyle(jointLineThickness, jointColor);
|
|
|
|
}
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
var bodyA = constraint.bodyA;
|
|
|
|
var bodyB = constraint.bodyB;
|
|
|
|
var start;
|
|
|
|
var end;
|
|
|
|
|
|
|
|
if (bodyA)
|
|
|
|
{
|
|
|
|
start = Vector.add(bodyA.position, constraint.pointA);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
start = constraint.pointA;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (constraint.render.type === 'pin')
|
|
|
|
{
|
2019-11-27 17:49:21 +00:00
|
|
|
if (!custom)
|
|
|
|
{
|
|
|
|
graphics.lineStyle(jointLineThickness, pinColor);
|
|
|
|
}
|
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.beginPath();
|
2019-11-27 17:49:21 +00:00
|
|
|
graphics.arc(start.x, start.y, pinSize, 0, 2 * Math.PI);
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.closePath();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (bodyB)
|
|
|
|
{
|
|
|
|
end = Vector.add(bodyB.position, constraint.pointB);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
end = constraint.pointB;
|
|
|
|
}
|
|
|
|
|
|
|
|
graphics.beginPath();
|
|
|
|
graphics.moveTo(start.x, start.y);
|
2018-03-26 03:44:32 +00:00
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
if (constraint.render.type === 'spring')
|
2018-03-26 03:44:32 +00:00
|
|
|
{
|
2019-11-27 17:49:21 +00:00
|
|
|
if (!custom)
|
|
|
|
{
|
|
|
|
graphics.lineStyle(jointLineThickness, springColor);
|
|
|
|
}
|
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
var delta = Vector.sub(end, start);
|
|
|
|
var normal = Vector.perp(Vector.normalise(delta));
|
|
|
|
var coils = Math.ceil(Common.clamp(constraint.length / 5, 12, 20));
|
|
|
|
var offset;
|
|
|
|
|
|
|
|
for (var j = 1; j < coils; j += 1)
|
|
|
|
{
|
|
|
|
offset = (j % 2 === 0) ? 1 : -1;
|
|
|
|
|
|
|
|
graphics.lineTo(
|
|
|
|
start.x + delta.x * (j / coils) + normal.x * offset * 4,
|
|
|
|
start.y + delta.y * (j / coils) + normal.y * offset * 4
|
|
|
|
);
|
|
|
|
}
|
2018-03-26 03:44:32 +00:00
|
|
|
}
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
graphics.lineTo(end.x, end.y);
|
|
|
|
}
|
|
|
|
|
2019-11-27 17:49:21 +00:00
|
|
|
graphics.strokePath();
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
if (constraint.render.anchors)
|
|
|
|
{
|
2019-11-27 17:49:21 +00:00
|
|
|
graphics.fillStyle(anchorColor);
|
|
|
|
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.beginPath();
|
2019-11-27 17:49:21 +00:00
|
|
|
graphics.arc(start.x, start.y, anchorSize, 0, 2 * Math.PI);
|
|
|
|
graphics.arc(end.x, end.y, anchorSize, 0, 2 * Math.PI);
|
2018-09-26 13:12:20 +00:00
|
|
|
graphics.closePath();
|
|
|
|
graphics.fillPath();
|
2018-03-26 03:44:32 +00:00
|
|
|
}
|
|
|
|
}
|
2017-11-27 03:45:46 +00:00
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
|
|
|
* [description]
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#fromPath
|
|
|
|
* @since 3.0.0
|
|
|
|
*
|
2018-03-19 15:01:14 +00:00
|
|
|
* @param {string} path - [description]
|
2018-03-19 00:10:32 +00:00
|
|
|
* @param {array} points - [description]
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
2018-03-19 00:10:32 +00:00
|
|
|
* @return {array} [description]
|
2018-02-12 13:48:38 +00:00
|
|
|
*/
|
2017-11-27 03:45:46 +00:00
|
|
|
fromPath: function (path, points)
|
|
|
|
{
|
|
|
|
if (points === undefined) { points = []; }
|
|
|
|
|
2018-02-16 19:17:49 +00:00
|
|
|
// var pathPattern = /L?\s*([-\d.e]+)[\s,]*([-\d.e]+)*/ig;
|
|
|
|
|
|
|
|
// eslint-disable-next-line no-useless-escape
|
2017-11-27 03:45:46 +00:00
|
|
|
var pathPattern = /L?\s*([\-\d\.e]+)[\s,]*([\-\d\.e]+)*/ig;
|
|
|
|
|
2018-02-16 18:17:51 +00:00
|
|
|
path.replace(pathPattern, function (match, x, y)
|
2017-11-27 03:45:46 +00:00
|
|
|
{
|
|
|
|
points.push({ x: parseFloat(x), y: parseFloat(y) });
|
|
|
|
});
|
|
|
|
|
|
|
|
return points;
|
2017-11-20 16:54:26 +00:00
|
|
|
},
|
|
|
|
|
2019-04-08 09:34:38 +00:00
|
|
|
/**
|
|
|
|
* Resets the internal collision IDs that Matter.JS uses for Body collision groups.
|
|
|
|
*
|
|
|
|
* You should call this before destroying your game if you need to restart the game
|
|
|
|
* again on the same page, without first reloading the page. Or, if you wish to
|
|
|
|
* consistently destroy a Scene that contains Matter.js and then run it again
|
|
|
|
* later in the same game.
|
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#resetCollisionIDs
|
|
|
|
* @since 3.17.0
|
|
|
|
*/
|
|
|
|
resetCollisionIDs: function ()
|
|
|
|
{
|
|
|
|
Body._nextCollidingGroupId = 1;
|
|
|
|
Body._nextNonCollidingGroupId = -1;
|
|
|
|
Body._nextCategory = 0x0001;
|
|
|
|
|
|
|
|
return this;
|
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-10-19 11:32:43 +00:00
|
|
|
* Will remove all Matter physics event listeners and clear the matter physics world,
|
|
|
|
* engine and any debug graphics, if any.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#shutdown
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-20 16:54:26 +00:00
|
|
|
shutdown: function ()
|
|
|
|
{
|
2018-04-13 11:07:27 +00:00
|
|
|
MatterEvents.off(this.engine);
|
2018-04-11 13:00:58 +00:00
|
|
|
|
|
|
|
this.removeAllListeners();
|
|
|
|
|
2017-11-29 23:36:35 +00:00
|
|
|
MatterWorld.clear(this.localWorld, false);
|
2018-02-12 13:48:38 +00:00
|
|
|
|
2017-11-29 23:36:35 +00:00
|
|
|
Engine.clear(this.engine);
|
2018-09-26 13:12:20 +00:00
|
|
|
|
|
|
|
if (this.drawDebug)
|
|
|
|
{
|
|
|
|
this.debugGraphic.destroy();
|
|
|
|
}
|
2017-11-20 16:54:26 +00:00
|
|
|
},
|
|
|
|
|
2018-02-12 13:48:38 +00:00
|
|
|
/**
|
2018-10-19 11:32:43 +00:00
|
|
|
* Will remove all Matter physics event listeners and clear the matter physics world,
|
|
|
|
* engine and any debug graphics, if any.
|
|
|
|
*
|
|
|
|
* After destroying the world it cannot be re-used again.
|
2018-02-12 13:48:38 +00:00
|
|
|
*
|
|
|
|
* @method Phaser.Physics.Matter.World#destroy
|
|
|
|
* @since 3.0.0
|
|
|
|
*/
|
2017-11-20 16:54:26 +00:00
|
|
|
destroy: function ()
|
|
|
|
{
|
2017-11-29 23:36:35 +00:00
|
|
|
this.shutdown();
|
2017-11-20 16:54:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
module.exports = World;
|