UNPKG

arcade-physics

Version:
746 lines 25.6 kB
"use strict"; /** * @author Richard Davey <rich@photonstorm.com> * @copyright 2020 Photon Storm Ltd. * @license {@link https://opensource.org/licenses/MIT|MIT License} */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.StaticBody = void 0; const Contains_1 = __importDefault(require("../../geom/circle/Contains")); const Contains_2 = __importDefault(require("../../geom/rectangle/Contains")); const const_1 = __importDefault(require("./const")); const Vector2_1 = require("../../math/Vector2"); class StaticBody { /** * A Static Arcade Physics Body. * * A Static Body never moves, and isn't automatically synchronized with its parent Game Object. * That means if you make any change to the parent's origin, position, or scale after creating or adding the body, you'll need to update the Static Body manually. * * A Static Body can collide with other Bodies, but is never moved by collisions. * * Its dynamic counterpart is {@link Body}. * * @param world The Arcade Physics simulation this Static Body belongs to. * @param x * @param y * @param width * @param height */ constructor(world, x, y, width = 64, height = 64) { this.world = world; /** Whether this Static Body is updated by the physics simulation. */ this.enable = true; /** Whether this Static Body's boundary is circular (`true`) or rectangular (`false`). */ this.isCircle = false; /** * If this Static Body is circular, this is the radius of the boundary, as set by {@link setCircle} in pixels. * Equal to `halfWidth`. */ this.radius = 0; /** * The offset set by {@link setCircle} or {@link setSize}. * * This doesn't affect the Static Body's position, because a Static Body does not follow its Game Object. */ this.offset = new Vector2_1.Vector2(); this._dx = 0; this._dy = 0; this.isBody = true; /** Whether the Static Body's boundary is drawn to the debug display. */ this.debugShowBody = world.defaults.debugShowStaticBody; /** The color of this Static Body on the debug display. */ this.debugBodyColor = world.defaults.staticBodyDebugColor; /** * The position of this Static Body within the simulation. * @type {Phaser.Math.Vector2} */ this.position = new Vector2_1.Vector2(x, y); /** * The width of the Static Body's boundary, in pixels. * If the Static Body is circular, this is also the Static Body's diameter. * * @type {number} */ this.width = width; /** * The height of the Static Body's boundary, in pixels. * If the Static Body is circular, this is also the Static Body's diameter. * * @type {number} */ this.height = height; /** * Half the Static Body's width, in pixels. * If the Static Body is circular, this is also the Static Body's radius. * * @type {number} */ this.halfWidth = Math.abs(this.width / 2); /** * Half the Static Body's height, in pixels. * If the Static Body is circular, this is also the Static Body's radius. * * @type {number} */ this.halfHeight = Math.abs(this.height / 2); /** * The center of the Static Body's boundary. * This is the midpoint of its `position` (top-left corner) and its bottom-right corner. * * @type {Phaser.Math.Vector2} */ this.center = new Vector2_1.Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); /** * A constant zero velocity used by the Arcade Physics simulation for calculations. * * @name Phaser.Physics.Arcade.StaticBody#velocity * @type {Phaser.Math.Vector2} * @readonly * @since 3.0.0 */ this.velocity = Vector2_1.Vector2.ZERO; /** * A constant `false` value expected by the Arcade Physics simulation. * * @name Phaser.Physics.Arcade.StaticBody#allowGravity * @type {boolean} * @readonly * @default false * @since 3.0.0 */ this.allowGravity = false; /** * Gravitational force applied specifically to this Body. Values are in pixels per second squared. Always zero for a Static Body. * * @name Phaser.Physics.Arcade.StaticBody#gravity * @type {Phaser.Math.Vector2} * @readonly * @since 3.0.0 */ this.gravity = Vector2_1.Vector2.ZERO; /** * Rebound, or restitution, following a collision, relative to 1. Always zero for a Static Body. * * @name Phaser.Physics.Arcade.StaticBody#bounce * @type {Phaser.Math.Vector2} * @readonly * @since 3.0.0 */ this.bounce = Vector2_1.Vector2.ZERO; // If true this Body will dispatch events /** * Whether the simulation emits a `worldbounds` event when this StaticBody collides with the world boundary. * Always false for a Static Body. (Static Bodies never collide with the world boundary and never trigger a `worldbounds` event.) * * @name Phaser.Physics.Arcade.StaticBody#onWorldBounds * @type {boolean} * @readonly * @default false * @since 3.0.0 */ this.onWorldBounds = false; /** * Whether the simulation emits a `collide` event when this StaticBody collides with another. * * @name Phaser.Physics.Arcade.StaticBody#onCollide * @type {boolean} * @default false * @since 3.0.0 */ this.onCollide = false; /** * Whether the simulation emits an `overlap` event when this StaticBody overlaps with another. * * @name Phaser.Physics.Arcade.StaticBody#onOverlap * @type {boolean} * @default false * @since 3.0.0 */ this.onOverlap = false; /** * The StaticBody's inertia, relative to a default unit (1). With `bounce`, this affects the exchange of momentum (velocities) during collisions. * * @name Phaser.Physics.Arcade.StaticBody#mass * @type {number} * @default 1 * @since 3.0.0 */ this.mass = 1; /** * Whether this object can be moved by collisions with another body. * * @name Phaser.Physics.Arcade.StaticBody#immovable * @type {boolean} * @default true * @since 3.0.0 */ this.immovable = true; /** * Sets if this Body can be pushed by another Body. * * A body that cannot be pushed will reflect back all of the velocity it is given to the * colliding body. If that body is also not pushable, then the separation will be split * between them evenly. * * If you want your body to never move or seperate at all, see the `setImmovable` method. * * By default, Static Bodies are not pushable. * * @name Phaser.Physics.Arcade.StaticBody#pushable * @type {boolean} * @default false * @since 3.50.0 * @see Phaser.GameObjects.Components.Pushable#setPushable */ this.pushable = false; /** * A flag disabling the default horizontal separation of colliding bodies. Pass your own `collideHandler` to the collider. * * @name Phaser.Physics.Arcade.StaticBody#customSeparateX * @type {boolean} * @default false * @since 3.0.0 */ this.customSeparateX = false; /** * A flag disabling the default vertical separation of colliding bodies. Pass your own `collideHandler` to the collider. * * @name Phaser.Physics.Arcade.StaticBody#customSeparateY * @type {boolean} * @default false * @since 3.0.0 */ this.customSeparateY = false; /** * The amount of horizontal overlap (before separation), if this Body is colliding with another. * * @name Phaser.Physics.Arcade.StaticBody#overlapX * @type {number} * @default 0 * @since 3.0.0 */ this.overlapX = 0; /** * The amount of vertical overlap (before separation), if this Body is colliding with another. * * @name Phaser.Physics.Arcade.StaticBody#overlapY * @type {number} * @default 0 * @since 3.0.0 */ this.overlapY = 0; /** * The amount of overlap (before separation), if this StaticBody is circular and colliding with another circular body. * * @name Phaser.Physics.Arcade.StaticBody#overlapR * @type {number} * @default 0 * @since 3.0.0 */ this.overlapR = 0; /** * Whether this StaticBody has ever overlapped with another while both were not moving. * * @name Phaser.Physics.Arcade.StaticBody#embedded * @type {boolean} * @default false * @since 3.0.0 */ this.embedded = false; /** * Whether this StaticBody interacts with the world boundary. * Always false for a Static Body. (Static Bodies never collide with the world boundary.) * * @name Phaser.Physics.Arcade.StaticBody#collideWorldBounds * @type {boolean} * @readonly * @default false * @since 3.0.0 */ this.collideWorldBounds = false; /** Whether this StaticBody is checked for collisions and for which directions. You can set `checkCollision.none = false` to disable collision checks. */ this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; /** * This property is kept for compatibility with Dynamic Bodies. * Avoid using it. * * @name Phaser.Physics.Arcade.StaticBody#touching * @type {Phaser.Types.Physics.Arcade.CollisionCallback} * @since 3.0.0 */ this.touching = { none: true, up: false, down: false, left: false, right: false }; /** * This property is kept for compatibility with Dynamic Bodies. * Avoid using it. * The values are always false for a Static Body. * * @name Phaser.Physics.Arcade.StaticBody#wasTouching * @type {Phaser.Types.Physics.Arcade.CollisionCallback} * @since 3.0.0 */ this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; /** * This property is kept for compatibility with Dynamic Bodies. * Avoid using it. * * @name Phaser.Physics.Arcade.StaticBody#blocked * @type {Phaser.Types.Physics.Arcade.CollisionCallback} * @since 3.0.0 */ this.blocked = { none: true, up: false, down: false, left: false, right: false }; /** * The StaticBody's physics type (static by default). * * @name Phaser.Physics.Arcade.StaticBody#physicsType * @type {number} * @default Phaser.Physics.Arcade.STATIC_BODY * @since 3.0.0 */ this.physicsType = const_1.default.PHYSICS_TYPE.STATIC_BODY; /** * The calculated change in the Static Body's horizontal position during the current step. * For a static body this is always zero. * * @name Phaser.Physics.Arcade.StaticBody#_dx * @type {number} * @private * @default 0 * @since 3.10.0 */ this._dx = 0; /** * The calculated change in the Static Body's vertical position during the current step. * For a static body this is always zero. * * @name Phaser.Physics.Arcade.StaticBody#_dy * @type {number} * @private * @default 0 * @since 3.10.0 */ this._dy = 0; } // used for the btree get minX() { return this.x; } get minY() { return this.y; } get maxX() { return this.x + this.width; } get maxY() { return this.y + this.height; } // /** // * Changes the Game Object this Body is bound to. // * First it removes its reference from the old Game Object, then sets the new one. // * You can optionally update the position and dimensions of this Body to reflect that of the new Game Object. // * // * @method Phaser.Physics.Arcade.StaticBody#setGameObject // * @since 3.1.0 // * // * @param {Phaser.GameObjects.GameObject} gameObject - The new Game Object that will own this Body. // * @param {boolean} [update=true] - Reposition and resize this Body to match the new Game Object? // * // * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. // * // * @see Phaser.Physics.Arcade.StaticBody#updateFromGameObject // */ // setGameObject(gameObject, update) { // if (gameObject && gameObject !== this.gameObject) { // // Remove this body from the old game object // // @ts-ignore // this.gameObject.body = null // gameObject.body = this // // Update our reference // this.gameObject = gameObject // } // if (update) { // this.updateFromGameObject() // } // return this // } preUpdate() { // nothing to pre-update on a static body. } update() { // nothing to update on a static body. } /** * Sets the size of the Static Body. * Resets the width and height to match current frame, if no width and height provided and a frame is found. * * @method Phaser.Physics.Arcade.StaticBody#setSize * @since 3.0.0 * * @param {number} [width] - The width of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame width. * @param {number} [height] - The height of the Static Body in pixels. Cannot be zero. If not given, and the parent Game Object has a frame, it will use the frame height. * * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ setSize(width, height) { this.world.staticTree.remove(this); this.width = width; this.height = height; this.halfWidth = Math.floor(width / 2); this.halfHeight = Math.floor(height / 2); this.updateCenter(); this.isCircle = false; this.radius = 0; this.world.staticTree.insert(this); return this; } /** * Sets this Static Body to have a circular body and sets its size and position. * * @method Phaser.Physics.Arcade.StaticBody#setCircle * @since 3.0.0 * * @param {number} radius - The radius of the StaticBody, in pixels. * @param {number} [offsetX] - The horizontal offset of the StaticBody from its Game Object, in pixels. * @param {number} [offsetY] - The vertical offset of the StaticBody from its Game Object, in pixels. * * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ setCircle(radius, offsetX, offsetY) { if (offsetX === undefined) { offsetX = this.offset.x; } if (offsetY === undefined) { offsetY = this.offset.y; } if (radius > 0) { this.world.staticTree.remove(this); this.isCircle = true; this.radius = radius; this.width = radius * 2; this.height = radius * 2; this.halfWidth = Math.floor(this.width / 2); this.halfHeight = Math.floor(this.height / 2); this.offset.set(offsetX, offsetY); this.updateCenter(); this.world.staticTree.insert(this); } else { this.isCircle = false; } return this; } /** * Updates the StaticBody's `center` from its `position` and dimensions. * * @method Phaser.Physics.Arcade.StaticBody#updateCenter * @since 3.0.0 */ updateCenter() { this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); } /** * Resets this Body to the given coordinates. Also positions its parent Game Object to the same coordinates. * * @method Phaser.Physics.Arcade.StaticBody#reset * @since 3.0.0 * * @param {number} [x] - The x coordinate to reset the body to. * @param {number} [y] - The y coordinate to reset the body to. */ reset(x, y) { this.world.staticTree.remove(this); this.position.set(x, y); this.updateCenter(); this.world.staticTree.insert(this); } /** * NOOP function. A Static Body cannot be stopped. * * @method Phaser.Physics.Arcade.StaticBody#stop * @since 3.0.0 * * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ stop() { return this; } /** * Returns the x and y coordinates of the top left and bottom right points of the StaticBody. * * @param {ArcadeBodyBounds} obj - The object which will hold the coordinates of the bounds. * @return {ArcadeBodyBounds} The same object that was passed with `x`, `y`, `right` and `bottom` values matching the respective values of the StaticBody. */ getBounds(obj) { obj.x = this.x; obj.y = this.y; obj.right = this.right; obj.bottom = this.bottom; return obj; } /** * Checks to see if a given x,y coordinate is colliding with this Static Body. * * @method Phaser.Physics.Arcade.StaticBody#hitTest * @since 3.0.0 * * @param {number} x - The x coordinate to check against this body. * @param {number} y - The y coordinate to check against this body. * * @return {boolean} `true` if the given coordinate lies within this body, otherwise `false`. */ hitTest(x, y) { return this.isCircle ? (0, Contains_1.default)(this, x, y) : (0, Contains_2.default)(this, x, y); } /** * NOOP * * @method Phaser.Physics.Arcade.StaticBody#postUpdate * @since 3.12.0 */ postUpdate() { } /** * The absolute (non-negative) change in this StaticBody's horizontal position from the previous step. Always zero. * * @method Phaser.Physics.Arcade.StaticBody#deltaAbsX * @since 3.0.0 * * @return {number} Always zero for a Static Body. */ deltaAbsX() { return 0; } /** * The absolute (non-negative) change in this StaticBody's vertical position from the previous step. Always zero. * * @method Phaser.Physics.Arcade.StaticBody#deltaAbsY * @since 3.0.0 * * @return {number} Always zero for a Static Body. */ deltaAbsY() { return 0; } /** * The change in this StaticBody's horizontal position from the previous step. Always zero. * * @method Phaser.Physics.Arcade.StaticBody#deltaX * @since 3.0.0 * * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. */ deltaX() { return 0; } /** * The change in this StaticBody's vertical position from the previous step. Always zero. * * @method Phaser.Physics.Arcade.StaticBody#deltaY * @since 3.0.0 * * @return {number} The change in this StaticBody's velocity from the previous step. Always zero. */ deltaY() { return 0; } /** * The change in this StaticBody's rotation from the previous step. Always zero. * * @method Phaser.Physics.Arcade.StaticBody#deltaZ * @since 3.0.0 * * @return {number} The change in this StaticBody's rotation from the previous step. Always zero. */ deltaZ() { return 0; } /** * Disables this Body and marks it for destruction during the next step. * * @method Phaser.Physics.Arcade.StaticBody#destroy * @since 3.0.0 */ destroy() { this.enable = false; this.world.pendingDestroy.add(this); } /** * Draws a graphical representation of the StaticBody for visual debugging purposes. * * @method Phaser.Physics.Arcade.StaticBody#drawDebug * @since 3.0.0 * * @param {CanvasRenderingContext2D} Context2D - The Context2D to use for the debug drawing of the StaticBody. */ drawDebug(ctx) { const pos = this.position; const x = pos.x + this.halfWidth; const y = pos.y + this.halfHeight; const defaultStrokeWidth = 1; const colorToHex = num => { num >>>= 0; let b = (num & 0xff).toString(16); let g = ((num & 0xff00) >>> 8).toString(16); let r = ((num & 0xff0000) >>> 16).toString(16); if (b === '0') b = '00'; if (g === '0') g = '00'; if (r === '0') r = '00'; return `#${b}${g}${r}`; }; const strokeRect = (x, y, w, h) => { ctx.rect(x, y, w, h); }; const lineStyle = (width, color, unknown) => { ctx.lineWidth = width; ctx.strokeStyle = colorToHex(color); }; const strokeCircle = (x, y, radius) => { ctx.arc(x, y, radius, 0, 2 * Math.PI); }; if (this.debugShowBody) { ctx.beginPath(); lineStyle(defaultStrokeWidth, this.debugBodyColor || 0x0000ff, 1); if (this.isCircle) { strokeCircle(x, y, this.width / 2); } else { strokeRect(pos.x, pos.y, this.width, this.height); } ctx.stroke(); } } /** * Indicates whether the StaticBody is going to be showing a debug visualization during postUpdate. * * @method Phaser.Physics.Arcade.StaticBody#willDrawDebug * @since 3.0.0 * * @return {boolean} Whether or not the StaticBody is going to show the debug visualization during postUpdate. */ willDrawDebug() { return this.debugShowBody; } /** * Sets the Mass of the StaticBody. Will set the Mass to 0.1 if the value passed is less than or equal to zero. * * @method Phaser.Physics.Arcade.StaticBody#setMass * @since 3.0.0 * * @param {number} value - The value to set the Mass to. Values of zero or less are changed to 0.1. * * @return {Phaser.Physics.Arcade.StaticBody} This Static Body object. */ setMass(value) { if (value <= 0) { // Causes havoc otherwise value = 0.1; } this.mass = value; return this; } /** * The x coordinate of the StaticBody. * * @name Phaser.Physics.Arcade.StaticBody#x * @type {number} * @since 3.0.0 */ get x() { return this.position.x; } set x(value) { this.world.staticTree.remove(this); this.position.x = value; this.world.staticTree.insert(this); } /** * The y coordinate of the StaticBody. * * @name Phaser.Physics.Arcade.StaticBody#y * @type {number} * @since 3.0.0 */ get y() { return this.position.y; } set y(value) { this.world.staticTree.remove(this); this.position.y = value; this.world.staticTree.insert(this); } /** * Returns the left-most x coordinate of the area of the StaticBody. * * @name Phaser.Physics.Arcade.StaticBody#left * @type {number} * @readonly * @since 3.0.0 */ get left() { return this.position.x; } /** * The right-most x coordinate of the area of the StaticBody. * * @name Phaser.Physics.Arcade.StaticBody#right * @type {number} * @readonly * @since 3.0.0 */ get right() { return this.position.x + this.width; } /** * The highest y coordinate of the area of the StaticBody. * * @name Phaser.Physics.Arcade.StaticBody#top * @type {number} * @readonly * @since 3.0.0 */ get top() { return this.position.y; } /** * The lowest y coordinate of the area of the StaticBody. (y + height) * * @name Phaser.Physics.Arcade.StaticBody#bottom * @type {number} * @readonly * @since 3.0.0 */ get bottom() { return this.position.y + this.height; } } exports.StaticBody = StaticBody; //# sourceMappingURL=StaticBody.js.map