From 3c91bbf236c51ee7845fd366d108cc2bb86a6031 Mon Sep 17 00:00:00 2001 From: Richard Davey Date: Thu, 9 Nov 2017 15:30:15 +0000 Subject: [PATCH] Added in the Arcade Physics utils functions. --- v3/src/physics/arcade/utils/AccelerateTo.js | 32 +++++++++++++++++ .../arcade/utils/AccelerateToObject.js | 23 ++++++++++++ v3/src/physics/arcade/utils/Closest.js | 27 ++++++++++++++ v3/src/physics/arcade/utils/Furthest.js | 27 ++++++++++++++ v3/src/physics/arcade/utils/MoveTo.js | 36 +++++++++++++++++++ v3/src/physics/arcade/utils/MoveToObject.js | 23 ++++++++++++ .../physics/arcade/utils/VelocityFromAngle.js | 20 +++++++++++ .../arcade/utils/VelocityFromRotation.js | 19 ++++++++++ 8 files changed, 207 insertions(+) create mode 100644 v3/src/physics/arcade/utils/AccelerateTo.js create mode 100644 v3/src/physics/arcade/utils/AccelerateToObject.js create mode 100644 v3/src/physics/arcade/utils/Closest.js create mode 100644 v3/src/physics/arcade/utils/Furthest.js create mode 100644 v3/src/physics/arcade/utils/MoveTo.js create mode 100644 v3/src/physics/arcade/utils/MoveToObject.js create mode 100644 v3/src/physics/arcade/utils/VelocityFromAngle.js create mode 100644 v3/src/physics/arcade/utils/VelocityFromRotation.js diff --git a/v3/src/physics/arcade/utils/AccelerateTo.js b/v3/src/physics/arcade/utils/AccelerateTo.js new file mode 100644 index 000000000..da831651a --- /dev/null +++ b/v3/src/physics/arcade/utils/AccelerateTo.js @@ -0,0 +1,32 @@ +/** +* Move the given display object towards the x/y coordinates at a steady velocity. +* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds. +* Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. +* Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. +* Note: The display object doesn't stop moving once it reaches the destination coordinates. +* Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) +* +* @method Phaser.Physics.Arcade#moveTo +* @param {any} displayObject - The display object to move. +* @param {any} destination - The display object to move towards. Can be any object but must have visible x/y properties. +* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) +* @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. +* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. +*/ +var AccelerateTo = function (gameObject, x, y, speed, xSpeedMax, ySpeedMax) +{ + if (speed === undefined) { speed = 60; } + + var angle = Math.atan2(y - gameObject.y, x - gameObject.x); + + gameObject.body.acceleration.setToPolar(angle, speed); + + if (xSpeedMax !== undefined && ySpeedMax !== undefined) + { + gameObject.body.maxVelocity.set(xSpeedMax, ySpeedMax); + } + + return angle; +}; + +module.exports = AccelerateTo; diff --git a/v3/src/physics/arcade/utils/AccelerateToObject.js b/v3/src/physics/arcade/utils/AccelerateToObject.js new file mode 100644 index 000000000..aba356a3b --- /dev/null +++ b/v3/src/physics/arcade/utils/AccelerateToObject.js @@ -0,0 +1,23 @@ +var AccelerateTo = require('./AccelerateTo'); + +/** +* Move the given display object towards the destination object at a steady velocity. +* If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds. +* Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. +* Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. +* Note: The display object doesn't stop moving once it reaches the destination coordinates. +* Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) +* +* @method Phaser.Physics.Arcade#AccelerateToObject +* @param {any} displayObject - The display object to move. +* @param {any} destination - The display object to move towards. Can be any object but must have visible x/y properties. +* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) +* @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. +* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. +*/ +var AccelerateToObject = function (gameObject, destination, speed, xSpeedMax, ySpeedMax) +{ + return AccelerateTo(gameObject, destination.x, destination.y, speed, xSpeedMax, ySpeedMax); +}; + +module.exports = AccelerateToObject; diff --git a/v3/src/physics/arcade/utils/Closest.js b/v3/src/physics/arcade/utils/Closest.js new file mode 100644 index 000000000..b9a2fb00a --- /dev/null +++ b/v3/src/physics/arcade/utils/Closest.js @@ -0,0 +1,27 @@ +var DistanceBetween = require('../../../math/distance/DistanceBetween'); + +var Closest = function (source) +{ + var bodies = this.tree.all(); + + var min = Number.MAX_SAFE_INTEGER; + var closest = null; + var x = source.x; + var y = source.y; + + for (var i = bodies.length - 1; i >= 0; i--) + { + var target = bodies[i]; + var distance = DistanceBetween(x, y, target.x, target.y); + + if (distance < min) + { + closest = target; + min = distance; + } + } + + return closest; +}; + +module.exports = Closest; diff --git a/v3/src/physics/arcade/utils/Furthest.js b/v3/src/physics/arcade/utils/Furthest.js new file mode 100644 index 000000000..794082c15 --- /dev/null +++ b/v3/src/physics/arcade/utils/Furthest.js @@ -0,0 +1,27 @@ +var DistanceBetween = require('../../../math/distance/DistanceBetween'); + +var Furthest = function (source) +{ + var bodies = this.tree.all(); + + var max = -1; + var farthest = null; + var x = source.x; + var y = source.y; + + for (var i = bodies.length - 1; i >= 0; i--) + { + var target = bodies[i]; + var distance = DistanceBetween(x, y, target.x, target.y); + + if (distance > max) + { + farthest = target; + max = distance; + } + } + + return farthest; +}; + +module.exports = Furthest; diff --git a/v3/src/physics/arcade/utils/MoveTo.js b/v3/src/physics/arcade/utils/MoveTo.js new file mode 100644 index 000000000..a99fa8c68 --- /dev/null +++ b/v3/src/physics/arcade/utils/MoveTo.js @@ -0,0 +1,36 @@ +var DistanceBetween = require('../../../math/distance/DistanceBetween'); + +/** +* Move the given display object towards the x/y coordinates at a steady velocity. +* If you specify a maxTime then it will adjust the speed (over-writing what you set) so it arrives at the destination in that number of seconds. +* Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. +* Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. +* Note: The display object doesn't stop moving once it reaches the destination coordinates. +* Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) +* +* @method Phaser.Physics.Arcade#moveTo +* @param {any} displayObject - The display object to move. +* @param {any} destination - The display object to move towards. Can be any object but must have visible x/y properties. +* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) +* @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. +* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. +*/ +var MoveTo = function (gameObject, x, y, speed, maxTime) +{ + if (speed === undefined) { speed = 60; } + if (maxTime === undefined) { maxTime = 0; } + + var angle = Math.atan2(y - gameObject.y, x - gameObject.x); + + if (maxTime > 0) + { + // We know how many pixels we need to move, but how fast? + speed = DistanceBetween(gameObject.x, gameObject.y, x, y) / (maxTime / 1000); + } + + gameObject.body.velocity.setToPolar(angle, speed); + + return angle; +}; + +module.exports = MoveTo; diff --git a/v3/src/physics/arcade/utils/MoveToObject.js b/v3/src/physics/arcade/utils/MoveToObject.js new file mode 100644 index 000000000..4743013a9 --- /dev/null +++ b/v3/src/physics/arcade/utils/MoveToObject.js @@ -0,0 +1,23 @@ +var MoveTo = require('./MoveTo'); + +/** +* Move the given display object towards the destination object at a steady velocity. +* If you specify a maxTime then it will adjust the speed (overwriting what you set) so it arrives at the destination in that number of seconds. +* Timings are approximate due to the way browser timers work. Allow for a variance of +- 50ms. +* Note: The display object does not continuously track the target. If the target changes location during transit the display object will not modify its course. +* Note: The display object doesn't stop moving once it reaches the destination coordinates. +* Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set drag or acceleration too high this object may not move at all) +* +* @method Phaser.Physics.Arcade#moveToObject +* @param {any} displayObject - The display object to move. +* @param {any} destination - The display object to move towards. Can be any object but must have visible x/y properties. +* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec) +* @param {number} [maxTime=0] - Time given in milliseconds (1000 = 1 sec). If set the speed is adjusted so the object will arrive at destination in the given number of ms. +* @return {number} The angle (in radians) that the object should be visually set to in order to match its new velocity. +*/ +var MoveToObject = function (gameObject, destination, speed, maxTime) +{ + return MoveTo(gameObject, destination.x, destination.y, speed, maxTime); +}; + +module.exports = MoveToObject; diff --git a/v3/src/physics/arcade/utils/VelocityFromAngle.js b/v3/src/physics/arcade/utils/VelocityFromAngle.js new file mode 100644 index 000000000..d29bf0fa7 --- /dev/null +++ b/v3/src/physics/arcade/utils/VelocityFromAngle.js @@ -0,0 +1,20 @@ +var DegToRad = require('../../../math/DegToRad'); + +/** +* Given the angle (in degrees) and speed calculate the velocity and return it as a Point object, or set it to the given point object. +* One way to use this is: velocityFromAngle(angle, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object. +* +* @method Phaser.Physics.Arcade#velocityFromAngle +* @param {number} angle - The angle in degrees calculated in clockwise positive direction (down = 90 degrees positive, right = 0 degrees positive, up = 90 degrees negative) +* @param {number} [speed=60] - The speed it will move, in pixels per second sq. +* @param {Phaser.Point|object} [point] - The Point object in which the x and y properties will be set to the calculated velocity. +* @return {Phaser.Point} - A Point where point.x contains the velocity x value and point.y contains the velocity y value. +*/ +var VelocityFromAngle = function (angle, speed, vec2) +{ + if (speed === undefined) { speed = 60; } + + return vec2.setToPolar(DegToRad(angle), speed); +}; + +module.exports = VelocityFromAngle; diff --git a/v3/src/physics/arcade/utils/VelocityFromRotation.js b/v3/src/physics/arcade/utils/VelocityFromRotation.js new file mode 100644 index 000000000..4e7f599c0 --- /dev/null +++ b/v3/src/physics/arcade/utils/VelocityFromRotation.js @@ -0,0 +1,19 @@ +/** +* Given the rotation (in radians) and speed calculate the velocity and return it as a Point object, or set it to the given point object. +* One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object. +* +* @method Phaser.Physics.Arcade#velocityFromRotation +* @param {number} rotation - The angle in radians. +* @param {number} [speed=60] - The speed it will move, in pixels per second sq. +* @param {Phaser.Point|object} [point] - The Point object in which the x and y properties will be set to the calculated velocity. +* @return {Phaser.Point} - A Point where point.x contains the velocity x value and point.y contains the velocity y value. +*/ + +var VelocityFromRotation = function (rotation, speed, vec2) +{ + if (speed === undefined) { speed = 60; } + + return vec2.setToPolar(rotation, speed); +}; + +module.exports = VelocityFromRotation;