UNPKG

arcade-physics

Version:
1,407 lines 48.6 kB
"use strict"; /** * @author Richard Davey <rich@photonstorm.com> * @author Benjamin D. Richards <benjamindrichards@gmail.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.Body = void 0; const const_1 = __importDefault(require("./const")); const events_1 = __importDefault(require("./events")); const Rectangle_1 = require("../../geom/rectangle/Rectangle"); const Contains_1 = __importDefault(require("../../geom/rectangle/Contains")); const Vector2_1 = require("../../math/Vector2"); /** A Dynamic Arcade Body. */ class Body { constructor(world, x, y, width = 64, height = 64) { /** Whether this Body is updated by the physics simulation. */ this.enable = true; /** Whether this Body is circular (true) or rectangular (false). */ this.isCircle = false; /** * If this Body is circular, this is the unscaled radius of the Body, as set by setCircle(), in source pixels. * The true radius is equal to `halfWidth`. */ this.radius = 0; /** Whether this Body's `rotation` is affected by its angular acceleration and angular velocity. */ this.allowRotation = true; /** The Body's velocity, in pixels per second. */ this.velocity = new Vector2_1.Vector2(); /** * The Body's change in position (due to velocity) at the last step, in pixels. * * The size of this value depends on the simulation's step rate. */ this.newVelocity = new Vector2_1.Vector2(); /** The Body's absolute maximum change in position, in pixels per step. */ this.deltaMax = new Vector2_1.Vector2(); /** The Body's change in velocity, in pixels per second squared. */ this.acceleration = new Vector2_1.Vector2(); /** Whether this Body's velocity is affected by its `drag`. */ this.allowDrag = true; /** * When `useDamping` is false (the default), this is absolute loss of velocity due to movement, in pixels per second squared. * * When `useDamping` is true, this is a damping multiplier between 0 and 1. * A value of 0 means the Body stops instantly. * A value of 0.01 mean the Body keeps 1% of its velocity per second, losing 99%. * A value of 0.1 means the Body keeps 10% of its velocity per second, losing 90%. * A value of 1 means the Body loses no velocity. * You can use very small values (e.g., 0.001) to stop the Body quickly. * * The x and y components are applied separately. * * Drag is applied only when `acceleration` is zero. */ this.drag = new Vector2_1.Vector2(); /** Whether this Body's position is affected by gravity (local or world). */ this.allowGravity = true; /** * Acceleration due to gravity (specific to this Body), in pixels per second squared. * Total gravity is the sum of this vector and the simulation's `gravity`. */ this.gravity = new Vector2_1.Vector2(); /** Rebound following a collision, relative to 1. */ this.bounce = new Vector2_1.Vector2(); /** * Rebound following a collision with the world boundary, relative to 1. * If null, `bounce` is used instead. */ this.worldBounce = null; /** Whether the simulation emits a `worldbounds` event when this Body collides with the world boundary (and `collideWorldBounds` is also true). */ this.onWorldBounds = false; /** Whether the simulation emits a `collide` event when this Body collides with another. */ this.onCollide = false; /** Whether the simulation emits an `overlap` event when this Body overlaps with another. */ this.onOverlap = false; /** * The Body's absolute maximum velocity, in pixels per second. * The horizontal and vertical components are applied separately. */ this.maxVelocity = new Vector2_1.Vector2(10000, 10000); /** * The maximum speed this Body is allowed to reach, in pixels per second. * * If not negative it limits the scalar value of speed. * * Any negative value means no maximum is being applied (the default). */ this.maxSpeed = -1; /** * If this Body is `immovable` and in motion, `friction` is the proportion of this Body's motion received by the riding Body on each axis, relative to 1. * The horizontal component (x) is applied only when two colliding Bodies are separated vertically. * The vertical component (y) is applied only when two colliding Bodies are separated horizontally. * The default value (1, 0) moves the riding Body horizontally in equal proportion to this Body and vertically not at all. */ this.friction = new Vector2_1.Vector2(1, 0); /** * If this Body is using `drag` for deceleration this property controls how the drag is applied. * If set to `true` drag will use a damping effect rather than a linear approach. If you are * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in * the game Asteroids) then you will get a far smoother and more visually correct deceleration * by using damping, avoiding the axis-drift that is prone with linear deceleration. * * If you enable this property then you should use far smaller `drag` values than with linear, as * they are used as a multiplier on the velocity. Values such as 0.05 will give a nice slow * deceleration. */ this.useDamping = false; /** The rate of change of this Body's `rotation`, in degrees per second. */ this.angularVelocity = 0; /** The Body's angular acceleration (change in angular velocity), in degrees per second squared. */ this.angularAcceleration = 0; /** * Loss of angular velocity due to angular movement, in degrees per second. * * Angular drag is applied only when angular acceleration is zero. */ this.angularDrag = 0; /** The Body's maximum angular velocity, in degrees per second. */ this.maxAngular = 1000; /** * The Body's inertia, relative to a default unit (1). * With `bounce`, this affects the exchange of momentum (velocities) during collisions. */ this.mass = 1; /** The calculated angle of this Body's velocity vector, in radians, during the last step. */ this.angle = 0; /** The calculated magnitude of the Body's velocity, in pixels per second, during the last step. */ this.speed = 0; /** * The direction of the Body's velocity, as calculated during the last step. * This is a numeric constant value (FACING_UP, FACING_DOWN, FACING_LEFT, FACING_RIGHT). * If the Body is moving on both axes, this describes motion on the vertical axis only. */ this.facing = const_1.default.FACING.FACING_NONE; /** Whether this Body can be moved by collisions with another Body. */ this.immovable = false; /** * 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, Dynamic Bodies are always pushable. */ this.pushable = true; /** Whether the Body's position and rotation are affected by its velocity, acceleration, drag, and gravity. */ this.moves = true; /** * A flag disabling the default horizontal separation of colliding bodies. * Pass your own `collideCallback` to the collider. */ this.customSeparateX = false; /** * A flag disabling the default vertical separation of colliding bodies. * Pass your own `collideCallback` to the collider. */ this.customSeparateY = false; /** The amount of horizontal overlap (before separation), if this Body is colliding with another. */ this.overlapX = 0; /** The amount of vertical overlap (before separation), if this Body is colliding with another. */ this.overlapY = 0; /** The amount of overlap (before separation), if this Body is circular and colliding with another circular body. */ this.overlapR = 0; /** Whether this Body is overlapped with another and both are not moving, on at least one axis. */ this.embedded = false; /** Whether this Body interacts with the world boundary. */ this.collideWorldBounds = false; /** * Whether this Body is checked for collisions and for which directions. * You can set `checkCollision.none = true` to disable collision checks. */ this.checkCollision = { none: false, up: true, down: true, left: true, right: true }; /** * Whether this Body is colliding with a Body or Static Body and in which direction. * In a collision where both bodies have zero velocity, `embedded` will be set instead. */ this.touching = { none: true, up: false, down: false, left: false, right: false }; /** This Body's `touching` value during the previous step. */ this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; /** * Whether this Body is colliding with a Static Body, a tile, or the world boundary. * In a collision with a Static Body, if this Body has zero velocity then `embedded` will be set instead. */ this.blocked = { none: true, up: false, down: false, left: false, right: false }; /** The Body's physics type (dynamic or static). */ this.physicsType = const_1.default.PHYSICS_TYPE.DYNAMIC_BODY; /** The calculated change in the Body's horizontal position during the last step. */ this._dx = 0; /** The calculated change in the Body's vertical position during the last step. */ this._dy = 0; /** The final calculated change in the Body's horizontal position as of `postUpdate`. */ this._tx = 0; /** The final calculated change in the Body's vertical position as of `postUpdate`. */ this._ty = 0; /** Stores the Game Object's bounds. */ this._bounds = new Rectangle_1.Rectangle(); this.isBody = true; this.world = world; this.debugShowBody = world.defaults.debugShowBody; this.debugShowVelocity = world.defaults.debugShowVelocity; this.debugBodyColor = world.defaults.bodyDebugColor; this.position = new Vector2_1.Vector2(x, y); this.prev = this.position.clone(); this.prevFrame = this.position.clone(); this.rotation = 0; this.preRotation = 0; this.width = width; this.height = height; this.sourceWidth = width; this.sourceHeight = height; this.halfWidth = Math.abs(width / 2); this.halfHeight = Math.abs(height / 2); this.center = new Vector2_1.Vector2(this.position.x + this.halfWidth, this.position.y + this.halfHeight); this.customBoundsRectangle = world.bounds; this._sx = 1; this._sy = 1; } // 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; } /** Updates the Body's `center` from its `position`, `width`, and `height`. */ updateCenter() { this.center.set(this.position.x + this.halfWidth, this.position.y + this.halfHeight); } /** * Prepares the Body for a physics step by resetting the `wasTouching`, `touching` and `blocked` states. * * This method is only called if the physics world is going to run a step this frame. */ resetFlags(clear = false) { // Store and reset collision flags const wasTouching = this.wasTouching; const touching = this.touching; const blocked = this.blocked; if (clear) { wasTouching.none = true; wasTouching.up = false; wasTouching.down = false; wasTouching.left = false; wasTouching.right = false; } else { wasTouching.none = touching.none; wasTouching.up = touching.up; wasTouching.down = touching.down; wasTouching.left = touching.left; wasTouching.right = touching.right; } touching.none = true; touching.up = false; touching.down = false; touching.left = false; touching.right = false; blocked.none = true; blocked.up = false; blocked.down = false; blocked.left = false; blocked.right = false; this.overlapR = 0; this.overlapX = 0; this.overlapY = 0; this.embedded = false; } /** * Syncs the position body position with the parent Game Object. * * This method is called every game frame, regardless if the world steps or not. * * @param willStep - Will this Body run an update as well? * @param delta - The delta time, in seconds, elapsed since the last frame. */ preUpdate(willStep, delta) { if (willStep) this.resetFlags(); // MOD(yandeu): not sure we can to call this here // this.updateFromGameObject() // this.rotation = this.transform.rotation this.preRotation = this.rotation; if (this.moves) { this.prev.x = this.position.x; this.prev.y = this.position.y; this.prevFrame.x = this.position.x; this.prevFrame.y = this.position.y; } if (willStep) this.update(delta); } /** * Performs a single physics step and updates the body velocity, angle, speed and other properties. * * This method can be called multiple times per game frame, depending on the physics step rate. * * The results are synced back to the Game Object in `postUpdate`. * * @param delta - The delta time, in seconds, elapsed since the last frame. */ update(delta) { this.prev.x = this.position.x; this.prev.y = this.position.y; if (this.moves) { this.world.updateMotion(this, delta); const vx = this.velocity.x; const vy = this.velocity.y; this.newVelocity.set(vx * delta, vy * delta); this.position.add(this.newVelocity); this.updateCenter(); this.angle = Math.atan2(vy, vx); this.speed = Math.sqrt(vx * vx + vy * vy); // Now the update will throw collision checks at the Body // And finally we'll integrate the new position back to the Sprite in postUpdate if (this.collideWorldBounds && this.checkWorldBounds() && this.onWorldBounds) { this.world.emit(events_1.default.WORLD_BOUNDS, this, this.blocked.up, this.blocked.down, this.blocked.left, this.blocked.right); } } this._dx = this.position.x - this.prev.x; this._dy = this.position.y - this.prev.y; } /** * Feeds the Body results back into the parent Game Object. * * This method is called every game frame, regardless if the world steps or not. */ postUpdate() { let dx = this.position.x - this.prevFrame.x; let dy = this.position.y - this.prevFrame.y; if (this.moves) { const mx = this.deltaMax.x; const my = this.deltaMax.y; if (mx !== 0 && dx !== 0) { if (dx < 0 && dx < -mx) { dx = -mx; } else if (dx > 0 && dx > mx) { dx = mx; } } if (my !== 0 && dy !== 0) { if (dy < 0 && dy < -my) { dy = -my; } else if (dy > 0 && dy > my) { dy = my; } } // this.gameObject.x += dx // this.gameObject.y += dy } if (dx < 0) { this.facing = const_1.default.FACING.FACING_LEFT; } else if (dx > 0) { this.facing = const_1.default.FACING.FACING_RIGHT; } if (dy < 0) { this.facing = const_1.default.FACING.FACING_UP; } else if (dy > 0) { this.facing = const_1.default.FACING.FACING_DOWN; } if (this.allowRotation) { // this.gameObject.angle += this.deltaZ() } this._tx = dx; this._ty = dy; } /** * Sets a custom collision boundary rectangle. Use if you want to have a custom * boundary instead of the world boundaries. * * @param bounds - The new boundary rectangle. Pass `null` to use the World bounds. */ setBoundsRectangle(bounds) { this.customBoundsRectangle = !bounds ? this.world.bounds : bounds; return this; } /** * Checks for collisions between this Body and the world boundary and separates them. * * Returns true if this Body is colliding with the world boundary. */ checkWorldBounds() { const pos = this.position; const bounds = this.customBoundsRectangle; const check = this.world.checkCollision; const bx = this.worldBounce ? -this.worldBounce.x : -this.bounce.x; const by = this.worldBounce ? -this.worldBounce.y : -this.bounce.y; let wasSet = false; if (pos.x < bounds.x && check.left) { pos.x = bounds.x; this.velocity.x *= bx; this.blocked.left = true; wasSet = true; } else if (this.right > bounds.right && check.right) { pos.x = bounds.right - this.width; this.velocity.x *= bx; this.blocked.right = true; wasSet = true; } if (pos.y < bounds.y && check.up) { pos.y = bounds.y; this.velocity.y *= by; this.blocked.up = true; wasSet = true; } else if (this.bottom > bounds.bottom && check.down) { pos.y = bounds.bottom - this.height; this.velocity.y *= by; this.blocked.down = true; wasSet = true; } if (wasSet) { this.blocked.none = false; this.updateCenter(); } return wasSet; } /** * Sizes and positions this Body, as a rectangle. * * @param width - The width of the Body in pixels. Cannot be zero. * @param height - The height of the Body in pixels. Cannot be zero. */ setSize(width, height) { this.sourceWidth = width; this.sourceHeight = height; this.width = this.sourceWidth * this._sx; this.height = this.sourceHeight * this._sy; this.halfWidth = Math.floor(this.width / 2); this.halfHeight = Math.floor(this.height / 2); this.updateCenter(); this.isCircle = false; this.radius = 0; return this; } /** * Sizes and positions this Body, as a circle. * * @param radius - The radius of the Body, in source pixels. */ setCircle(radius) { if (radius > 0) { this.isCircle = true; this.radius = radius; this.sourceWidth = radius * 2; this.sourceHeight = radius * 2; this.width = this.sourceWidth * this._sx; this.height = this.sourceHeight * this._sy; this.halfWidth = Math.floor(this.width / 2); this.halfHeight = Math.floor(this.height / 2); this.updateCenter(); } else { this.isCircle = false; } return this; } /** * Resets this Body at the new coordinates. * If the Body had any velocity or acceleration it is lost as a result of calling this. * * @param x - The horizontal position to place the Body. * @param y - The vertical position to place the Body. */ reset(x, y) { this.stop(); this.position.set(x, y); this.prev.copy(this.position); this.prevFrame.copy(this.position); // this.rotation = gameObject.angle // this.preRotation = gameObject.angle this.updateCenter(); this.resetFlags(true); } /** Sets acceleration, velocity, and speed to zero. */ stop() { this.velocity.set(0); this.acceleration.set(0); this.speed = 0; this.angularVelocity = 0; this.angularAcceleration = 0; return this; } /** * Copies the coordinates of this Body's edges into an object. * * @param {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} obj - An object to copy the values into. * * @return {Phaser.Types.Physics.Arcade.ArcadeBodyBounds} - An object with {x, y, right, bottom}. */ getBounds(obj) { obj.x = this.x; obj.y = this.y; obj.right = this.right; obj.bottom = this.bottom; return obj; } /** * Tests if the coordinates are within this Body. * * Returns true if (x, y) is within this Body. * * @param x - The horizontal coordinate. * @param y - The vertical coordinate. */ hitTest(x, y) { if (!this.isCircle) { return (0, Contains_1.default)(this, x, y); } // Check if x/y are within the bounds first if (this.radius > 0 && x >= this.left && x <= this.right && y >= this.top && y <= this.bottom) { const dx = (this.center.x - x) * (this.center.x - x); const dy = (this.center.y - y) * (this.center.y - y); return dx + dy <= this.radius * this.radius; } return false; } /** * Whether this Body is touching a tile or the world boundary while moving down. * * Returns true if touching. */ onFloor() { return this.blocked.down; } /** * Whether this Body is touching a tile or the world boundary while moving up. * * Returns true if touching. */ onCeiling() { return this.blocked.up; } /** * Whether this Body is touching a tile or the world boundary while moving left or right. * * Returns true if touching. */ onWall() { return this.blocked.left || this.blocked.right; } /** * The absolute (non-negative) change in this Body's horizontal position from the previous step. * * Returns the delta value. */ deltaAbsX() { return this._dx > 0 ? this._dx : -this._dx; } /** * The absolute (non-negative) change in this Body's vertical position from the previous step. * * Returns the delta value. */ deltaAbsY() { return this._dy > 0 ? this._dy : -this._dy; } /** * The change in this Body's horizontal position from the previous step. * This value is set during the Body's update phase. * * As a Body can update multiple times per step this may not hold the final * delta value for the Body. In this case, please see the `deltaXFinal` method. * * Returns the delta value. */ deltaX() { return this._dx; } /** * The change in this Body's vertical position from the previous step. * This value is set during the Body's update phase. * * As a Body can update multiple times per step this may not hold the final * delta value for the Body. In this case, please see the `deltaYFinal` method. * * Returns the delta value. */ deltaY() { return this._dy; } /** * The change in this Body's horizontal position from the previous game update. * * This value is set during the `postUpdate` phase and takes into account the * `deltaMax` and final position of the Body. * * Because this value is not calculated until `postUpdate`, you must listen for it * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will * not be calculated by that point. If you _do_ use these values in `update` they * will represent the delta from the _previous_ game frame. * * Returns the final delta x value. */ deltaXFinal() { return this._tx; } /** * The change in this Body's vertical position from the previous game update. * * This value is set during the `postUpdate` phase and takes into account the * `deltaMax` and final position of the Body. * * Because this value is not calculated until `postUpdate`, you must listen for it * during a Scene `POST_UPDATE` or `RENDER` event, and not in `update`, as it will * not be calculated by that point. If you _do_ use these values in `update` they * will represent the delta from the _previous_ game frame. * * Returns the final delta y value. */ deltaYFinal() { return this._ty; } /** * The change in this Body's rotation from the previous step, in degrees. * * Returns the delta value. */ deltaZ() { return this.rotation - this.preRotation; } /** * Disables this Body and marks it for deletion by the simulation. * * @method Phaser.Physics.Arcade.Body#destroy * @since 3.0.0 */ destroy() { this.enable = false; if (this.world) { this.world.pendingDestroy.add(this); } } /** * Draws this Body and its velocity, if enabled. * * @method Phaser.Physics.Arcade.Body#drawDebug * @since 3.0.0 * * @param {CanvasRenderingContext2D} Context2D - The Context2D to draw on. */ drawDebug(ctx) { var _a, _b; const pos = this.position; const x = pos.x + this.halfWidth; const y = pos.y + this.halfHeight; const defaultStrokeWidth = 1; const lineBetween = (x1, y1, x2, y2) => { ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); }; 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 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); if (this.isCircle) { strokeCircle(x, y, this.width / 2); } else { // Only draw the sides where checkCollision is true, similar to debugger in layer if (this.checkCollision.up) { lineBetween(pos.x, pos.y, pos.x + this.width, pos.y); } if (this.checkCollision.right) { lineBetween(pos.x + this.width, pos.y, pos.x + this.width, pos.y + this.height); } if (this.checkCollision.down) { lineBetween(pos.x, pos.y + this.height, pos.x + this.width, pos.y + this.height); } if (this.checkCollision.left) { lineBetween(pos.x, pos.y, pos.x, pos.y + this.height); } } ctx.stroke(); } if (this.debugShowVelocity) { ctx.beginPath(); lineStyle(defaultStrokeWidth, ((_b = (_a = this.world) === null || _a === void 0 ? void 0 : _a.defaults) === null || _b === void 0 ? void 0 : _b.velocityDebugColor) || 0x00ff00, 1); lineBetween(x, y, x + this.velocity.x / 2, y + this.velocity.y / 2); ctx.stroke(); } } /** * Whether this Body will be drawn to the debug display. * * @method Phaser.Physics.Arcade.Body#willDrawDebug * @since 3.0.0 * * @return {boolean} True if either `debugShowBody` or `debugShowVelocity` are enabled. */ willDrawDebug() { return this.debugShowBody || this.debugShowVelocity; } /** * Sets whether this Body collides with the world boundary. * * Optionally also sets the World Bounce and `onWorldBounds` values. * * @method Phaser.Physics.Arcade.Body#setCollideWorldBounds * @since 3.0.0 * * @param {boolean} [value=true] - `true` if the Body should collide with the world bounds, otherwise `false`. * @param {number} [bounceX] - If given this replaces the Body's `worldBounce.x` value. * @param {number} [bounceY] - If given this replaces the Body's `worldBounce.y` value. * @param {boolean} [onWorldBounds] - If given this replaces the Body's `onWorldBounds` value. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setCollideWorldBounds(value, bounceX, bounceY, onWorldBounds) { if (value === undefined) { value = true; } this.collideWorldBounds = value; const setBounceX = bounceX !== undefined; const setBounceY = bounceY !== undefined; if (setBounceX || setBounceY) { if (!this.worldBounce) { this.worldBounce = new Vector2_1.Vector2(); } if (setBounceX) { this.worldBounce.x = bounceX; } if (setBounceY) { this.worldBounce.y = bounceY; } } if (onWorldBounds !== undefined) { this.onWorldBounds = onWorldBounds; } return this; } /** * Sets the Body's velocity. * * @method Phaser.Physics.Arcade.Body#setVelocity * @since 3.0.0 * * @param {number} x - The horizontal velocity, in pixels per second. * @param {number} [y=x] - The vertical velocity, in pixels per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setVelocity(x, y) { this.velocity.set(x, y); x = this.velocity.x; y = this.velocity.y; this.speed = Math.sqrt(x * x + y * y); return this; } /** * Sets the Body's horizontal velocity. * * @method Phaser.Physics.Arcade.Body#setVelocityX * @since 3.0.0 * * @param {number} value - The velocity, in pixels per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setVelocityX(value) { this.velocity.x = value; const x = value; const y = this.velocity.y; this.speed = Math.sqrt(x * x + y * y); return this; } /** * Sets the Body's vertical velocity. * * @method Phaser.Physics.Arcade.Body#setVelocityY * @since 3.0.0 * * @param {number} value - The velocity, in pixels per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setVelocityY(value) { this.velocity.y = value; const x = this.velocity.x; const y = value; this.speed = Math.sqrt(x * x + y * y); return this; } /** * Sets the Body's maximum velocity. * * @method Phaser.Physics.Arcade.Body#setMaxVelocity * @since 3.10.0 * * @param {number} x - The horizontal velocity, in pixels per second. * @param {number} [y=x] - The vertical velocity, in pixels per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setMaxVelocity(x, y) { this.maxVelocity.set(x, y); return this; } /** * Sets the Body's maximum horizontal velocity. * * @method Phaser.Physics.Arcade.Body#setMaxVelocityX * @since 3.50.0 * * @param {number} value - The maximum horizontal velocity, in pixels per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setMaxVelocityX(value) { this.maxVelocity.x = value; return this; } /** * Sets the Body's maximum vertical velocity. * * @method Phaser.Physics.Arcade.Body#setMaxVelocityY * @since 3.50.0 * * @param {number} value - The maximum vertical velocity, in pixels per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setMaxVelocityY(value) { this.maxVelocity.y = value; return this; } /** * Sets the maximum speed the Body can move. * * @method Phaser.Physics.Arcade.Body#setMaxSpeed * @since 3.16.0 * * @param {number} value - The maximum speed value, in pixels per second. Set to a negative value to disable. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setMaxSpeed(value) { this.maxSpeed = value; return this; } /** * Sets the Body's bounce. * * @method Phaser.Physics.Arcade.Body#setBounce * @since 3.0.0 * * @param {number} x - The horizontal bounce, relative to 1. * @param {number} y - The vertical bounce, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setBounce(x, y) { this.bounce.set(x, y); return this; } /** * Sets the Body's horizontal bounce. * * @method Phaser.Physics.Arcade.Body#setBounceX * @since 3.0.0 * * @param {number} value - The bounce, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setBounceX(value) { this.bounce.x = value; return this; } /** * Sets the Body's vertical bounce. * * @method Phaser.Physics.Arcade.Body#setBounceY * @since 3.0.0 * * @param {number} value - The bounce, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setBounceY(value) { this.bounce.y = value; return this; } /** * Sets the Body's acceleration. * * @method Phaser.Physics.Arcade.Body#setAcceleration * @since 3.0.0 * * @param {number} x - The horizontal component, in pixels per second squared. * @param {number} y - The vertical component, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAcceleration(x, y) { this.acceleration.set(x, y); return this; } /** * Sets the Body's horizontal acceleration. * * @method Phaser.Physics.Arcade.Body#setAccelerationX * @since 3.0.0 * * @param {number} value - The acceleration, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAccelerationX(value) { this.acceleration.x = value; return this; } /** * Sets the Body's vertical acceleration. * * @method Phaser.Physics.Arcade.Body#setAccelerationY * @since 3.0.0 * * @param {number} value - The acceleration, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAccelerationY(value) { this.acceleration.y = value; return this; } /** * Enables or disables drag. * * @method Phaser.Physics.Arcade.Body#setAllowDrag * @since 3.9.0 * @see Phaser.Physics.Arcade.Body#allowDrag * * @param {boolean} [value=true] - `true` to allow drag on this body, or `false` to disable it. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAllowDrag(value) { if (value === undefined) { value = true; } this.allowDrag = value; return this; } /** * Enables or disables gravity's effect on this Body. * * @method Phaser.Physics.Arcade.Body#setAllowGravity * @since 3.9.0 * @see Phaser.Physics.Arcade.Body#allowGravity * * @param {boolean} [value=true] - `true` to allow gravity on this body, or `false` to disable it. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAllowGravity(value) { if (value === undefined) { value = true; } this.allowGravity = value; return this; } /** * Enables or disables rotation. * * @method Phaser.Physics.Arcade.Body#setAllowRotation * @since 3.9.0 * @see Phaser.Physics.Arcade.Body#allowRotation * * @param {boolean} [value=true] - `true` to allow rotation on this body, or `false` to disable it. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAllowRotation(value) { if (value === undefined) { value = true; } this.allowRotation = value; return this; } /** * Sets the Body's drag. * * @method Phaser.Physics.Arcade.Body#setDrag * @since 3.0.0 * * @param {number} x - The horizontal component, in pixels per second squared. * @param {number} y - The vertical component, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setDrag(x, y) { this.drag.set(x, y); return this; } /** * If this Body is using `drag` for deceleration this property controls how the drag is applied. * If set to `true` drag will use a damping effect rather than a linear approach. If you are * creating a game where the Body moves freely at any angle (i.e. like the way the ship moves in * the game Asteroids) then you will get a far smoother and more visually correct deceleration * by using damping, avoiding the axis-drift that is prone with linear deceleration. * * If you enable this property then you should use far smaller `drag` values than with linear, as * they are used as a multiplier on the velocity. Values such as 0.95 will give a nice slow * deceleration, where-as smaller values, such as 0.5 will stop an object almost immediately. * * @method Phaser.Physics.Arcade.Body#setDamping * @since 3.50.0 * * @param {boolean} value - `true` to use damping, or `false` to use drag. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setDamping(value) { this.useDamping = value; return this; } /** * Sets the Body's horizontal drag. * * @method Phaser.Physics.Arcade.Body#setDragX * @since 3.0.0 * * @param {number} value - The drag, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setDragX(value) { this.drag.x = value; return this; } /** * Sets the Body's vertical drag. * * @method Phaser.Physics.Arcade.Body#setDragY * @since 3.0.0 * * @param {number} value - The drag, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setDragY(value) { this.drag.y = value; return this; } /** * Sets the Body's gravity. * * @method Phaser.Physics.Arcade.Body#setGravity * @since 3.0.0 * * @param {number} x - The horizontal component, in pixels per second squared. * @param {number} y - The vertical component, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setGravity(x, y) { this.gravity.set(x, y); return this; } /** * Sets the Body's horizontal gravity. * * @method Phaser.Physics.Arcade.Body#setGravityX * @since 3.0.0 * * @param {number} value - The gravity, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setGravityX(value) { this.gravity.x = value; return this; } /** * Sets the Body's vertical gravity. * * @method Phaser.Physics.Arcade.Body#setGravityY * @since 3.0.0 * * @param {number} value - The gravity, in pixels per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setGravityY(value) { this.gravity.y = value; return this; } /** * Sets the Body's friction. * * @method Phaser.Physics.Arcade.Body#setFriction * @since 3.0.0 * * @param {number} x - The horizontal component, relative to 1. * @param {number} y - The vertical component, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setFriction(x, y) { this.friction.set(x, y); return this; } /** * Sets the Body's horizontal friction. * * @method Phaser.Physics.Arcade.Body#setFrictionX * @since 3.0.0 * * @param {number} value - The friction value, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setFrictionX(value) { this.friction.x = value; return this; } /** * Sets the Body's vertical friction. * * @method Phaser.Physics.Arcade.Body#setFrictionY * @since 3.0.0 * * @param {number} value - The friction value, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setFrictionY(value) { this.friction.y = value; return this; } /** * Sets the Body's angular velocity. * * @method Phaser.Physics.Arcade.Body#setAngularVelocity * @since 3.0.0 * * @param {number} value - The velocity, in degrees per second. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAngularVelocity(value) { this.angularVelocity = value; return this; } /** * Sets the Body's angular acceleration. * * @method Phaser.Physics.Arcade.Body#setAngularAcceleration * @since 3.0.0 * * @param {number} value - The acceleration, in degrees per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAngularAcceleration(value) { this.angularAcceleration = value; return this; } /** * Sets the Body's angular drag. * * @method Phaser.Physics.Arcade.Body#setAngularDrag * @since 3.0.0 * * @param {number} value - The drag, in degrees per second squared. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setAngularDrag(value) { this.angularDrag = value; return this; } /** * Sets the Body's mass. * * @method Phaser.Physics.Arcade.Body#setMass * @since 3.0.0 * * @param {number} value - The mass value, relative to 1. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setMass(value) { this.mass = value; return this; } /** * Sets the Body's `immovable` property. * * @method Phaser.Physics.Arcade.Body#setImmovable * @since 3.0.0 * * @param {boolean} [value=true] - The value to assign to `immovable`. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setImmovable(value) { if (value === undefined) { value = true; } this.immovable = value; return this; } /** * Sets the Body's `enable` property. * * @method Phaser.Physics.Arcade.Body#setEnable * @since 3.15.0 * * @param {boolean} [value=true] - The value to assign to `enable`. * * @return {Phaser.Physics.Arcade.Body} This Body object. */ setEnable(value) { if (value === undefined) { value = true; } this.enable = value; return this; } /** * This is an internal handler, called by the `ProcessX` function as part * of the collision step. You should almost never call this directly. * * @method Phaser.Physics.Arcade.Body#processX * @since 3.50.0 * * @param {number} x - The amount to add to the Body position. * @param {number} [vx] - The amount to add to the Body velocity. * @param {boolean} [left] - Set the blocked.left value? * @param {boolean} [right] - Set the blocked.right value? */ processX(x, vx, left, right) { this.x += x; this.updateCenter(); if (vx !== null) { this.velocity.x = vx; } const blocked = this.blocked; if (left) { blocked.left = true; } if (right) { blocked.right = true; } } /** * This is an internal handler, called by the `ProcessY` function as part * of the collision step. You should almost never call this directly. * * @method Phaser.Physics.Arcade.Body#processY * @since 3.50.0 * * @param {number} y - The amount to add to the Body position. * @param {number} [vy] - The amount to add to the Body velocity. * @param {boolean} [up] - Set the blocked.up value? * @param {boolean} [down] - Set the blocked.down value? */ processY(y, vy, up, down) { this.y += y; this.updateCenter(); if (vy !== null) { this.velocity.y = vy; } const blocked = this.blocked; if (up) { blocked.up = true; } if (down) { blocked.down = true; } } /** * The Bodys horizontal position (left edge). * * @name Phaser.Physics.Arcade.Body#x * @type {number} * @since 3.0.0 */ get x() { return this.position.x; } set x(value) { this.position.x = value; } /** * The Bodys vertical position (top edge). * * @name Phaser.Physics.Arcade.Body#y * @type {number} * @since 3.0.0 */ get y() { return this.position.y; } set y(value) { this.position.y = value; } /** * The left edge of the Body. Identical to x. * * @name Phaser.Physics.Arcade.Body#left * @type {number} * @readonly * @since 3.0.0 */ get left() { return this.position.x; } /** * The right edge of the Body. * * @name Phaser.Physics.Arcade.Body#right * @type {number} * @readonly * @since 3.0.0 */ get right() { return this.position.x + this.width; } /** * The top edge of the Body. Identical to y. * * @name Phaser.Physics.Arcade.Body#top * @type {number} * @readonly * @since 3.0.0 */ get top() { return this.position.y; } /** * The bottom edge of this Body. * * @name Phaser.Physics.Arcade.Body#bottom * @type {number} * @readonly * @since 3.0.0 */ get bottom() { return this.position.y + this.height; } } exports.Body = Body; //# sourceMappingURL=Body.js.map