1
0
Fork 0

Simpler and more realistic ship movement

This commit is contained in:
Michaël Lemaire 2019-05-23 18:29:14 +02:00
parent 79e0a6bc83
commit bc32e7d81a
3 changed files with 10 additions and 61 deletions

View File

@ -243,7 +243,7 @@ module TK.SpaceTac.UI {
sprite.radius.setAlpha(0);
sprite.setPosition(owner.arena_x, owner.arena_y);
sprite.sprite.setRotation(owner.arena_angle);
await this.view.animations.moveInSpace(sprite, drone.x, drone.y, angle, sprite.sprite, speed);
await this.view.animations.moveTo(sprite, drone.x, drone.y, angle, sprite.sprite, speed, speed * 2);
await this.view.animations.addAnimation(sprite.radius, { alpha: 1 }, 500 / speed, "Cubic.easeIn");
} else {
sprite.setPosition(drone.x, drone.y);

View File

@ -263,16 +263,10 @@ module TK.SpaceTac.UI {
/**
* Move the sprite to a location
*
* Return the duration of animation
*/
async moveToArenaLocation(x: number, y: number, facing_angle: number, speed = 1, engine = true): Promise<void> {
if (speed) {
if (engine) {
await this.arena.view.animations.moveInSpace(this, x, y, facing_angle, this.sprite, speed);
} else {
await this.arena.view.animations.moveTo(this, x, y, facing_angle, this.sprite, speed);
}
await this.arena.view.animations.moveTo(this, x, y, facing_angle, this.sprite, speed, speed * 1.5);
} else {
this.setPosition(x, y);
this.sprite.setRotation(facing_angle);

View File

@ -216,10 +216,8 @@ module TK.SpaceTac.UI {
* Interpolate a rotation value
*
* This will take into account the 2*pi modulo
*
* Returns the duration
*/
rotationTween(obj: Phaser.GameObjects.Components.Transform, dest: number, speed = 1, easing = "Cubic.easeInOut"): Promise<void> {
rotationTween(obj: Phaser.GameObjects.Components.Transform, dest: number, duration = 1000, easing = "Cubic.easeInOut"): Promise<void> {
// Immediately change the object's current rotation to be in range (-pi,pi)
let value = UITools.normalizeAngle(obj.rotation);
obj.setRotation(value);
@ -231,8 +229,6 @@ module TK.SpaceTac.UI {
} else if (value - dest < -Math.PI) {
dest -= 2 * Math.PI;
}
let distance = Math.abs(UITools.normalizeAngle(dest - value)) / Math.PI;
let duration = distance * 2000 / speed;
// Tween
return this.addAnimation(obj, { rotation: dest }, duration, easing);
@ -241,59 +237,18 @@ module TK.SpaceTac.UI {
/**
* Move an object linearly to another position
*
* Returns the animation duration.
* The animation will be based on speed
*/
moveTo(obj: Phaser.GameObjects.Components.Transform, x: number, y: number, angle: number, rotated_obj = obj, speed = 1, ease = true): Promise<void> {
let duration = arenaDistance(obj, { x: x, y: y }) * 2 / speed;
moveTo(obj: Phaser.GameObjects.Components.Transform, x: number, y: number, angle: number, rotated_obj = obj, speed = 1, rotspeed = speed, ease = true): Promise<void> {
let duration = Math.max(
arenaDistance(obj, { x: x, y: y }) * 2 / speed,
Math.abs(angularDifference(rotated_obj.rotation, angle)) * 1000 / rotspeed,
);
return Promise.all([
this.rotationTween(rotated_obj, angle, speed, ease ? "Cubic.easeInOut" : "Linear"),
this.rotationTween(rotated_obj, angle, duration * speed / rotspeed, ease ? "Cubic.easeInOut" : "Linear"),
this.addAnimation(obj, { x: x, y: y }, duration, ease ? "Quad.easeInOut" : "Linear"),
]).then(nop);
}
/**
* Make an object move toward a location in space, with a ship-like animation.
*
* Returns the animation duration.
*/
moveInSpace(obj: Phaser.GameObjects.Components.Transform, x: number, y: number, angle: number, rotated_obj = obj, speed = 1): Promise<void> {
this.killPrevious(obj, ["x", "y"]);
if (x == obj.x && y == obj.y) {
let distance = Math.abs(angularDifference(rotated_obj.rotation, angle));
return this.rotationTween(rotated_obj, angle, speed);
} else {
this.killPrevious(rotated_obj, ["rotation"]);
let distance = Target.newFromLocation(obj.x, obj.y).getDistanceTo(Target.newFromLocation(x, y));
let duration = Math.sqrt(distance / 1000) * 3000 / speed;
let curve_force = distance * 0.4;
let prevx = obj.x;
let prevy = obj.y;
let xpts = [obj.x, obj.x + Math.cos(rotated_obj.rotation) * curve_force, x - Math.cos(angle) * curve_force, x];
let ypts = [obj.y, obj.y + Math.sin(rotated_obj.rotation) * curve_force, y - Math.sin(angle) * curve_force, y];
let fobj = { t: 0 };
return new Promise(resolve => {
this.tweens.add({
targets: [fobj],
t: 1,
duration: duration,
ease: "Sine.easeInOut",
onComplete: resolve,
onUpdate: () => {
obj.setPosition(
Phaser.Math.Interpolation.CubicBezier(fobj.t, xpts[0], xpts[1], xpts[2], xpts[3]),
Phaser.Math.Interpolation.CubicBezier(fobj.t, ypts[0], ypts[1], ypts[2], ypts[3]),
)
if (prevx != obj.x || prevy != obj.y) {
rotated_obj.setRotation(Math.atan2(obj.y - prevy, obj.x - prevx));
}
prevx = obj.x;
prevy = obj.y;
}
})
});
}
}
}
}