phaser
Version:
A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.
285 lines (244 loc) • 10.9 kB
JavaScript
/**
* @author Richard Davey <rich@photonstorm.com>
* @copyright 2013-2023 Photon Storm Ltd.
* @license {@link https://opensource.org/licenses/MIT|MIT License}
*/
var Bodies = require('../lib/factory/Bodies');
var Body = require('../lib/body/Body');
var FuzzyEquals = require('../../../math/fuzzy/Equal');
var GetFastValue = require('../../../utils/object/GetFastValue');
var PhysicsEditorParser = require('../PhysicsEditorParser');
var PhysicsJSONParser = require('../PhysicsJSONParser');
var Vertices = require('../lib/geometry/Vertices');
/**
* Enables a Matter-enabled Game Object to set its Body. Should be used as a mixin and not directly.
*
* @namespace Phaser.Physics.Matter.Components.SetBody
* @since 3.0.0
*/
var SetBody = {
/**
* Set this Game Objects Matter physics body to be a rectangle shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setRectangle
* @since 3.0.0
*
* @param {number} width - Width of the rectangle.
* @param {number} height - Height of the rectangle.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setRectangle: function (width, height, options)
{
return this.setBody({ type: 'rectangle', width: width, height: height }, options);
},
/**
* Set this Game Objects Matter physics body to be a circle shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setCircle
* @since 3.0.0
*
* @param {number} radius - The radius of the circle.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setCircle: function (radius, options)
{
return this.setBody({ type: 'circle', radius: radius }, options);
},
/**
* Set this Game Objects Matter physics body to be a polygon shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setPolygon
* @since 3.0.0
*
* @param {number} radius - The "radius" of the polygon, i.e. the distance from its center to any vertex. This is also the radius of its circumcircle.
* @param {number} sides - The number of sides the polygon will have.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setPolygon: function (radius, sides, options)
{
return this.setBody({ type: 'polygon', sides: sides, radius: radius }, options);
},
/**
* Set this Game Objects Matter physics body to be a trapezoid shape.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setTrapezoid
* @since 3.0.0
*
* @param {number} width - The width of the trapezoid Body.
* @param {number} height - The height of the trapezoid Body.
* @param {number} slope - The slope of the trapezoid. 0 creates a rectangle, while 1 creates a triangle. Positive values make the top side shorter, while negative values make the bottom side shorter.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setTrapezoid: function (width, height, slope, options)
{
return this.setBody({ type: 'trapezoid', width: width, height: height, slope: slope }, options);
},
/**
* Set this Game Object to use the given existing Matter Body.
*
* The body is first removed from the world before being added to this Game Object.
*
* @method Phaser.Physics.Matter.Components.SetBody#setExistingBody
* @since 3.0.0
*
* @param {MatterJS.BodyType} body - The Body this Game Object should use.
* @param {boolean} [addToWorld=true] - Should the body be immediately added to the World?
*
* @return {this} This Game Object instance.
*/
setExistingBody: function (body, addToWorld)
{
if (addToWorld === undefined) { addToWorld = true; }
if (this.body)
{
this.world.remove(this.body, true);
}
this.body = body;
for (var i = 0; i < body.parts.length; i++)
{
body.parts[i].gameObject = this;
}
var _this = this;
body.destroy = function destroy ()
{
_this.world.remove(_this.body, true);
_this.body.gameObject = null;
};
if (addToWorld)
{
if (this.world.has(body))
{
// Because it could be part of another Composite
this.world.remove(body, true);
}
this.world.add(body);
}
if (this._originComponent)
{
var rx = body.render.sprite.xOffset;
var ry = body.render.sprite.yOffset;
var comx = body.centerOfMass.x;
var comy = body.centerOfMass.y;
if (FuzzyEquals(comx, 0.5) && FuzzyEquals(comy, 0.5))
{
this.setOrigin(rx + 0.5, ry + 0.5);
}
else
{
var cx = body.centerOffset.x;
var cy = body.centerOffset.y;
this.setOrigin(rx + (cx / this.displayWidth), ry + (cy / this.displayHeight));
}
}
return this;
},
/**
* Set this Game Object to create and use a new Body based on the configuration object given.
*
* Calling this methods resets all previous properties you may have set on the body, including
* plugins, mass, friction, collision categories, etc. So be sure to re-apply these as needed.
*
* @method Phaser.Physics.Matter.Components.SetBody#setBody
* @since 3.0.0
*
* @param {(string|Phaser.Types.Physics.Matter.MatterSetBodyConfig)} config - Either a string, such as `circle`, or a Matter Set Body Configuration object.
* @param {Phaser.Types.Physics.Matter.MatterBodyConfig} [options] - An optional Body configuration object that is used to set initial Body properties on creation.
*
* @return {this} This Game Object instance.
*/
setBody: function (config, options)
{
if (!config)
{
return this;
}
var body;
// Allow them to do: shape: 'circle' instead of shape: { type: 'circle' }
if (typeof config === 'string')
{
// Using defaults
config = { type: config };
}
var shapeType = GetFastValue(config, 'type', 'rectangle');
var bodyX = GetFastValue(config, 'x', this._tempVec2.x);
var bodyY = GetFastValue(config, 'y', this._tempVec2.y);
var bodyWidth = GetFastValue(config, 'width', this.width);
var bodyHeight = GetFastValue(config, 'height', this.height);
switch (shapeType)
{
case 'rectangle':
body = Bodies.rectangle(bodyX, bodyY, bodyWidth, bodyHeight, options);
break;
case 'circle':
var radius = GetFastValue(config, 'radius', Math.max(bodyWidth, bodyHeight) / 2);
var maxSides = GetFastValue(config, 'maxSides', 25);
body = Bodies.circle(bodyX, bodyY, radius, options, maxSides);
break;
case 'trapezoid':
var slope = GetFastValue(config, 'slope', 0.5);
body = Bodies.trapezoid(bodyX, bodyY, bodyWidth, bodyHeight, slope, options);
break;
case 'polygon':
var sides = GetFastValue(config, 'sides', 5);
var pRadius = GetFastValue(config, 'radius', Math.max(bodyWidth, bodyHeight) / 2);
body = Bodies.polygon(bodyX, bodyY, sides, pRadius, options);
break;
case 'fromVertices':
case 'fromVerts':
var verts = GetFastValue(config, 'verts', null);
if (verts)
{
// Has the verts array come from Vertices.fromPath, or is it raw?
if (typeof verts === 'string')
{
verts = Vertices.fromPath(verts);
}
if (this.body && !this.body.hasOwnProperty('temp'))
{
Body.setVertices(this.body, verts);
body = this.body;
}
else
{
var flagInternal = GetFastValue(config, 'flagInternal', false);
var removeCollinear = GetFastValue(config, 'removeCollinear', 0.01);
var minimumArea = GetFastValue(config, 'minimumArea', 10);
body = Bodies.fromVertices(bodyX, bodyY, verts, options, flagInternal, removeCollinear, minimumArea);
}
}
break;
case 'fromPhysicsEditor':
body = PhysicsEditorParser.parseBody(bodyX, bodyY, config, options);
break;
case 'fromPhysicsTracer':
body = PhysicsJSONParser.parseBody(bodyX, bodyY, config, options);
break;
}
if (body)
{
this.setExistingBody(body, config.addToWorld);
}
return this;
}
};
module.exports = SetBody;