UNPKG

phaser

Version:

A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.

285 lines (244 loc) 10.9 kB
/** * @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;