mirror of
https://github.com/wassname/phaser-plugin-isometric.git
synced 2026-08-30 11:28:40 +08:00
Added arcade-physics utility functions
This commit is contained in:
+213
-7
@@ -966,7 +966,7 @@ Phaser.Plugin.Isometric.Arcade.prototype = {
|
||||
/**
|
||||
* Find the distance between two display objects (like Sprites).
|
||||
*
|
||||
* @method Phaser.Plugin.Isometric.Arcade#distanceBetween
|
||||
* @method Phaser.Plugin.Isometric.Isometric.Arcade#distanceBetween
|
||||
* @param {any} source - The Display Object to test from.
|
||||
* @param {any} target - The Display Object to test to.
|
||||
* @return {number} The distance between the source and target objects.
|
||||
@@ -1001,29 +1001,235 @@ Phaser.Plugin.Isometric.Arcade.prototype = {
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Find the distance between a display object (like a Sprite) and the given x/y/z coordinates.
|
||||
* The calculation is made from the display objects x/y/z coordinate. This may be the top-left if its anchor hasn't been changed.
|
||||
* If you need to calculate from the center of a display object instead use the method distanceBetweenCenters()
|
||||
*
|
||||
* @method Phaser.Plugin.Isometric.Arcade#distanceToXYZ
|
||||
* @param {any} displayObject - The Display Object to test from.
|
||||
* @param {any} displayObjectBody - The Display Object to test from.
|
||||
* @param {number} x - The x coordinate to test to.
|
||||
* @param {number} y - The y coordinate to test to.
|
||||
* @param {number} z - The y coordinate to test to
|
||||
* @return {number} The distance between the object and the x/y coordinates.
|
||||
*/
|
||||
distanceToXYZ: function (displayObject, x, y, z) {
|
||||
distanceToXYZ: function (displayObjectBody, x, y, z) {
|
||||
|
||||
this._dx = displayObject.x - x;
|
||||
this._dy = displayObject.y - y;
|
||||
this._dz = displayObject.z - z;
|
||||
this._dx = displayObjectBody.x - x;
|
||||
this._dy = displayObjectBody.y - y;
|
||||
this._dz = displayObjectBody.z - z;
|
||||
|
||||
return Math.sqrt(this._dx * this._dx + this._dy * this._dy + this._dz * this._dz);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the distance between a display object (like a Sprite) and a Pointer. If no Pointer is given the Input.activePointer is used.
|
||||
* The calculation is made from the display objects x/y coordinate. This may be the top-left if its anchor hasn't been changed.
|
||||
* If you need to calculate from the center of a display object instead use the method distanceBetweenCenters()
|
||||
* The distance to the Pointer is returned in isometric distance.
|
||||
*
|
||||
* @method Phaser.Physics.Arcade#distanceToPointer
|
||||
* @param {any} displayObjectBody - The Display Object to test from.
|
||||
* @param {Phaser.Pointer} [pointer] - The Phaser.Pointer to test to. If none is given then Input.activePointer is used.
|
||||
* @return {number} The distance between the object and the Pointer.
|
||||
*/
|
||||
distanceToPointer: function (displayObjectBody, pointer) {
|
||||
|
||||
pointer = pointer || this.game.input.activePointer;
|
||||
var isoPointer = this.game.iso.unproject(pointer.position,undefined,displayObjectBody.z);
|
||||
isoPointer.z = displayObjectBody.z;
|
||||
var a = this.anglesToXYZ(displayObjectBody, isoPointer.x, isoPointer.y, isoPointer.z);
|
||||
|
||||
return a.r;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the angles in radians between a display object (like a IsoSprite) and the given x/y/z coordinate.
|
||||
*
|
||||
* @method Phaser.Physics.Isometric.Isometric.Arcade#anglesToXYZ
|
||||
* @param {any} displayObjectBody - The Display Object to test from.
|
||||
* @param {number} x - The x coordinate to get the angle to.
|
||||
* @param {number} y - The y coordinate to get the angle to.
|
||||
* @param {number} z - The z coordinate to get the angle to.
|
||||
* @return {number} The angle in radians between displayObjectBody.x/y to Pointer.x/y
|
||||
*/
|
||||
anglesToXYZ: function (displayObjectBody, x, y, z) {
|
||||
|
||||
// Spherical polar coordinates
|
||||
var r = this.distanceToXYZ(displayObjectBody, x, y, z);
|
||||
var theta = Math.atan2(y - displayObjectBody.y, x - displayObjectBody.x);
|
||||
var phi = Math.acos((z - displayObjectBody.z)/ r);
|
||||
|
||||
return {r:r,theta:theta,phi:phi};
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Find the angle in radians between a display object (like a Sprite) and a Pointer, taking their x/y and center into account.
|
||||
* This is not the visual angle but the angle in the isometric co-ordinate system.
|
||||
*
|
||||
* @method Phaser.Physics.Isometric.Arcade#angleToPointer
|
||||
* @param {any} displayObjectBody - The Display Object to test from.
|
||||
* @param {Phaser.Pointer} [pointer] - The Phaser.Pointer to test to. If none is given then Input.activePointer is used.
|
||||
* @return {number} The (isometric) angle in radians between displayObjectBody.x/y to Pointer.x/y.
|
||||
*/
|
||||
angleToPointer: function(displayObjectBody, pointer) {
|
||||
|
||||
pointer = pointer || this.game.input.activePointer;
|
||||
var isoPointer = this.game.iso.unproject(pointer.position,undefined,displayObjectBody.z);
|
||||
isoPointer.z = displayObjectBody.z;
|
||||
var a = this.anglesToXYZ(displayObjectBody, isoPointer.x, isoPointer.y, isoPointer.z);
|
||||
|
||||
return a.theta;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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} theta - The angle in radians for x,y in the isometric co-ordinate system
|
||||
* @param {number} [phi=Math.PI/2] - The angle in radians for z in the isometric co-ordinate system
|
||||
* @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.Plugin.Isometric.Point3} - A Point where point.x contains the velocity x value and so on for y and z.
|
||||
*/
|
||||
velocityFromAngles: function (theta, phi, speed, point) {
|
||||
|
||||
if (phi === undefined) { phi = Math.sin(Math.PI/2); }
|
||||
if (speed === undefined) { speed = 60; }
|
||||
point = point || new Phaser.Point();
|
||||
|
||||
return new Phaser.Plugin.Isometric.Point3(
|
||||
Math.cos(theta) * Math.sin(phi) * speed,
|
||||
Math.sin(theta) * Math.sin(phi) * speed,
|
||||
Math.cos(phi) * speed
|
||||
);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the acceleration.x/y property on the display object so it will move towards the x/y coordinates at the given speed (in pixels per second sq.)
|
||||
* You must give a maximum speed value, beyond which the display object won't go any faster.
|
||||
* 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.
|
||||
*
|
||||
* @method Phaser.Physics.Isometric.Arcade#accelerateToXYZ
|
||||
* @param {any} displayObject - The display object to move.
|
||||
* @param {number} x - The x coordinate to accelerate towards.
|
||||
* @param {number} y - The y coordinate to accelerate towards.
|
||||
* @param {number} z - The z coordinate to accelerate towards.
|
||||
* @param {number} [speed=60] - The speed it will accelerate in pixels per second.
|
||||
* @param {number} [xSpeedMax=500] - The maximum x velocity the display object can reach.
|
||||
* @param {number} [ySpeedMax=500] - The maximum y velocity the display object can reach.
|
||||
* @param {number} [zSpeedMax=500] - The maximum z velocity the display object can reach.
|
||||
* @return {number} The angle (in radians) that the object should be visually set to in order to match its new trajectory.
|
||||
*/
|
||||
accelerateToXYZ: function(displayObject, x, y, z, speed, xSpeedMax, ySpeedMax, zSpeedMax) {
|
||||
|
||||
if (speed === undefined) { speed = 60; }
|
||||
if (xSpeedMax === undefined) { xSpeedMax = 500; }
|
||||
if (ySpeedMax === undefined) { ySpeedMax = 500; }
|
||||
if (zSpeedMax === undefined) { zSpeedMax = 500; }
|
||||
|
||||
var a = this.anglesToXYZ(displayObject.body, x, y,z);
|
||||
var v = this.velocityFromAngles(a.theta,a.phi,speed);
|
||||
|
||||
displayObject.body.acceleration.setTo(v.x,v.y,v.z);
|
||||
displayObject.body.maxVelocity.setTo(xSpeedMax, ySpeedMax, zSpeedMax);
|
||||
|
||||
return a.theta;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.Isometric.Arcade#moveToXYZ
|
||||
* @param {any} displayObject - The display object to move, must have an isoArcade body.
|
||||
* @param {number} x - The x coordinate to move towards.
|
||||
* @param {number} y - The y coordinate to move towards.
|
||||
* @param {number} z - The z coordinate to move towards.
|
||||
* @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.
|
||||
*/
|
||||
moveToXYZ: function(displayObject, x, y, z, speed, maxTime) {
|
||||
|
||||
if (typeof speed === 'undefined') {
|
||||
speed = 60;
|
||||
}
|
||||
if (typeof maxTime === 'undefined') {
|
||||
maxTime = 0;
|
||||
}
|
||||
|
||||
if (maxTime > 0) {
|
||||
// We know how many pixels we need to move, but how fast?
|
||||
speed = this.distanceToXYZ(displayObject.body, x, y ,z) / (maxTime / 1000);
|
||||
}
|
||||
var a = this.anglesToXYZ(displayObject.body, x, y,z);
|
||||
var v = this.velocityFromAngles(a.theta,a.phi,speed);
|
||||
|
||||
console.log(displayObject.id,v);
|
||||
displayObject.body.velocity.copyFrom(v);
|
||||
console.log(displayObject.id,displayObject.body.velocity);
|
||||
|
||||
return a.theta;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.Isometric.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/z 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.
|
||||
*/
|
||||
moveToObject: function (displayObject, destination, speed, maxTime) {
|
||||
|
||||
return this.moveToXYZ(displayObject, destination.x, destination.y, destination.z, speed, maxTime);
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* For isoArcade move the given display object towards the pointer at a steady velocity. If no pointer is given it will use Phaser.Input.activePointer.
|
||||
* 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.
|
||||
*
|
||||
* @method Phaser.Physics.Isometric.Arcade#moveToPointer
|
||||
* @param {any} displayObject - The display object to move.
|
||||
* @param {number} [speed=60] - The speed it will move, in pixels per second (default is 60 pixels/sec)
|
||||
* @param {Phaser.Pointer} [pointer] - The pointer to move towards. Defaults to Phaser.Input.activePointer.
|
||||
* @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.
|
||||
*/
|
||||
moveToPointer: function(displayObject, speed, pointer, maxTime) {
|
||||
|
||||
pointer = pointer || this.game.input.activePointer;
|
||||
var isoPointer = this.game.iso.unproject(pointer.position,undefined,displayObject.body.z);
|
||||
isoPointer.z = displayObject.body.z;
|
||||
return this.moveToXYZ(displayObject, isoPointer.x, isoPointer.y, isoPointer.z, speed, maxTime);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
Phaser.Physics.prototype.isoArcade = null;
|
||||
|
||||
Reference in New Issue
Block a user