Fixed tooltip and fading animation issues
This commit is contained in:
parent
55cd64e3c7
commit
29303e2688
2
TODO
2
TODO
|
@ -1,5 +1,4 @@
|
|||
* UI: Use a common component class, and a layer abstraction
|
||||
* UI: Fix tooltip sometimes being enormous
|
||||
* Character sheet: add tooltips (on values, slots and equipments)
|
||||
* Character sheet: add initial character creation
|
||||
* Character sheet: disable interaction during battle (except for loot screen)
|
||||
|
@ -16,6 +15,7 @@
|
|||
* All things displayed in battle should be updated from LogProcess forwarding, not from current game state
|
||||
* Drones: add tooltip
|
||||
* Drones: add hull points and take area damage
|
||||
* Show power usage/recovery in action bar, on action hover
|
||||
* More sound effects
|
||||
* Add a battle log display
|
||||
* Organize arena objects and information in layers
|
||||
|
|
|
@ -12,6 +12,9 @@ module TS.SpaceTac.UI {
|
|||
// Input and key bindings
|
||||
inputs: InputManager;
|
||||
|
||||
// Animations
|
||||
animations: Animations;
|
||||
|
||||
// Timing
|
||||
timer: Timer;
|
||||
|
||||
|
@ -49,6 +52,9 @@ module TS.SpaceTac.UI {
|
|||
// Notifications
|
||||
this.messages = new Messages(this);
|
||||
|
||||
// Animations
|
||||
this.animations = new Animations(this.game.tweens);
|
||||
|
||||
// Input manager
|
||||
this.inputs = new InputManager(this);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ module TS.SpaceTac.UI {
|
|||
setInteractive(interactive: boolean) {
|
||||
this.interactive = interactive;
|
||||
|
||||
Animation.setVisibility(this.game, this.icon_waiting, !this.interactive, 100);
|
||||
this.battleview.animations.setVisible(this.icon_waiting, !this.interactive, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -162,7 +162,7 @@ module TS.SpaceTac.UI {
|
|||
// Set the selected state on this icon
|
||||
setSelected(selected: boolean) {
|
||||
this.selected = selected;
|
||||
Animation.setVisibility(this.game, this.layer_selected, this.selected, 300);
|
||||
this.battleview.animations.setVisible(this.layer_selected, this.selected, 300);
|
||||
}
|
||||
|
||||
// Update the active status, from the action canBeUsed result
|
||||
|
@ -170,7 +170,7 @@ module TS.SpaceTac.UI {
|
|||
var old_active = this.active;
|
||||
this.active = !this.action.checkCannotBeApplied(this.ship);
|
||||
if (force || (this.active != old_active)) {
|
||||
Animation.setVisibility(this.game, this.layer_active, this.active, 500);
|
||||
this.battleview.animations.setVisible(this.layer_active, this.active, 500);
|
||||
this.game.tweens.create(this.layer_icon).to({ alpha: this.active ? 1 : 0.3 }, 500).start();
|
||||
this.input.useHandCursor = this.active;
|
||||
}
|
||||
|
@ -181,7 +181,7 @@ module TS.SpaceTac.UI {
|
|||
var old_fading = this.fading;
|
||||
this.fading = this.active && (this.action.checkCannotBeApplied(this.ship, remaining_ap) != null);
|
||||
if (this.fading != old_fading) {
|
||||
Animation.setVisibility(this.game, this.layer_active, this.active && !this.fading, 500);
|
||||
this.battleview.animations.setVisible(this.layer_active, this.active && !this.fading, 500);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,9 +70,9 @@ module TS.SpaceTac.UI {
|
|||
this.shortcut.setText("");
|
||||
}
|
||||
|
||||
Animation.fadeIn(this.game, this, 200, 0.9);
|
||||
this.bar.battleview.animations.show(this, 200, 0.9);
|
||||
} else {
|
||||
Animation.fadeOut(this.game, this, 200);
|
||||
this.bar.battleview.animations.hide(this, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ module TS.SpaceTac.UI {
|
|||
if (animate) {
|
||||
sprite.position.set(drone.owner.arena_x, drone.owner.arena_y);
|
||||
sprite.rotation = drone.owner.arena_angle;
|
||||
let move_duration = Animation.moveInSpace(sprite, drone.x, drone.y, angle);
|
||||
let move_duration = Animations.moveInSpace(sprite, drone.x, drone.y, angle);
|
||||
this.game.tweens.create(sprite.radius).from({ alpha: 0 }, 500, Phaser.Easing.Cubic.In, true, move_duration);
|
||||
|
||||
return move_duration + 500;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
module TS.SpaceTac.UI {
|
||||
// Ship sprite in the arena (BattleView)
|
||||
export class ArenaShip extends Phaser.Group {
|
||||
// Link to the view
|
||||
battleview: BattleView;
|
||||
|
||||
// Link to displayed ship
|
||||
ship: Ship;
|
||||
|
||||
|
@ -25,10 +28,10 @@ module TS.SpaceTac.UI {
|
|||
// Create a ship sprite usable in the Arena
|
||||
constructor(parent: Arena, ship: Ship) {
|
||||
super(parent.game);
|
||||
let battleview = parent.battleview;
|
||||
this.battleview = parent.battleview;
|
||||
|
||||
this.ship = ship;
|
||||
this.enemy = this.ship.getPlayer() != battleview.player;
|
||||
this.enemy = this.ship.getPlayer() != this.battleview.player;
|
||||
|
||||
// Add ship sprite
|
||||
this.sprite = new Phaser.Button(this.game, 0, 0, "ship-" + ship.model + "-sprite");
|
||||
|
@ -58,7 +61,11 @@ module TS.SpaceTac.UI {
|
|||
this.addChild(this.effects);
|
||||
|
||||
// Handle input on ship sprite
|
||||
Tools.setHoverClick(this.sprite, () => battleview.cursorOnShip(ship), () => battleview.cursorOffShip(ship), () => battleview.cursorClicked());
|
||||
Tools.setHoverClick(this.sprite,
|
||||
() => this.battleview.cursorOnShip(ship),
|
||||
() => this.battleview.cursorOffShip(ship),
|
||||
() => this.battleview.cursorClicked()
|
||||
);
|
||||
|
||||
// Set location
|
||||
this.position.set(ship.arena_x, ship.arena_y);
|
||||
|
@ -67,7 +74,7 @@ module TS.SpaceTac.UI {
|
|||
// Set the hovered state on this ship
|
||||
// This will toggle the hover effect
|
||||
setHovered(hovered: boolean) {
|
||||
Animation.setVisibility(this.game, this.hover, hovered, 200);
|
||||
this.battleview.animations.setVisible(this.hover, hovered, 200);
|
||||
}
|
||||
|
||||
// Set the playing state on this ship
|
||||
|
@ -84,7 +91,7 @@ module TS.SpaceTac.UI {
|
|||
this.displayEffect("stasis", false);
|
||||
}
|
||||
this.frame.alpha = dead ? 0.5 : 1.0;
|
||||
Animation.setVisibility(this.game, this.stasis, dead, 400);
|
||||
this.battleview.animations.setVisible(this.stasis, dead, 400);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -94,7 +101,7 @@ module TS.SpaceTac.UI {
|
|||
*/
|
||||
moveTo(x: number, y: number, facing_angle: number, animate = true): number {
|
||||
if (animate) {
|
||||
return Animation.moveInSpace(this, x, y, facing_angle, this.sprite);
|
||||
return Animations.moveInSpace(this, x, y, facing_angle, this.sprite);
|
||||
} else {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
module TS.SpaceTac.UI {
|
||||
// One item in a ship list (used in BattleView)
|
||||
export class ShipListItem extends Phaser.Button {
|
||||
// Reference to the view
|
||||
view: BattleView;
|
||||
|
||||
// Reference to the ship game object
|
||||
ship: Ship;
|
||||
|
||||
|
@ -28,6 +31,7 @@ module TS.SpaceTac.UI {
|
|||
// Create a ship button for the battle ship list
|
||||
constructor(list: ShipList, x: number, y: number, ship: Ship, owned: boolean) {
|
||||
super(list.battleview.game, x, y, owned ? "battle-shiplist-own" : "battle-shiplist-enemy");
|
||||
this.view = list.battleview;
|
||||
|
||||
this.ship = ship;
|
||||
|
||||
|
@ -104,7 +108,7 @@ module TS.SpaceTac.UI {
|
|||
|
||||
// Set the hovered status
|
||||
setHovered(hovered: boolean) {
|
||||
Animation.setVisibility(this.game, this.layer_hover, hovered, 200);
|
||||
this.view.animations.setVisible(this.layer_hover, hovered, 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,9 +118,9 @@ module TS.SpaceTac.UI {
|
|||
|
||||
this.stasis.visible = !ship.alive;
|
||||
|
||||
Animation.fadeIn(this.game, this, 200);
|
||||
this.battleview.animations.show(this, 200);
|
||||
} else {
|
||||
Animation.fadeOut(this.game, this, 200);
|
||||
this.battleview.animations.hide(this, 200);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ module TS.SpaceTac.UI {
|
|||
*/
|
||||
setSelected(selected: boolean) {
|
||||
this.loadTexture(selected ? "character-ship-selected" : "character-ship");
|
||||
Animation.setVisibility(this.game, this.levelup, this.ship.getAvailableUpgradePoints() > 0, 200);
|
||||
this.sheet.view.animations.setVisible(this.levelup, this.ship.getAvailableUpgradePoints() > 0, 200);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
module TS.SpaceTac.UI.Specs {
|
||||
describe("Animation", () => {
|
||||
let testgame = setupEmptyView();
|
||||
|
||||
it("animates rotation", function () {
|
||||
let obj = { rotation: -Math.PI * 2.5 };
|
||||
let tween = testgame.ui.tweens.create(obj);
|
||||
let result = Animation.rotationTween(tween, Math.PI * 0.25, 1, Phaser.Easing.Linear.None);
|
||||
expect(result).toEqual(750);
|
||||
expect(tween.generateData(4)).toEqual([
|
||||
{ rotation: -Math.PI * 0.25 },
|
||||
{ rotation: 0 },
|
||||
{ rotation: Math.PI * 0.25 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
36
src/ui/common/Animations.spec.ts
Normal file
36
src/ui/common/Animations.spec.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
module TS.SpaceTac.UI.Specs {
|
||||
describe("Animations", () => {
|
||||
let testgame = setupEmptyView();
|
||||
|
||||
it("shows and hides objects", function () {
|
||||
let obj = { visible: false, alpha: 0.5 };
|
||||
|
||||
expect(testgame.baseview.animations.simulate(obj, 'alpha')).toEqual([]);
|
||||
|
||||
testgame.baseview.animations.show(obj);
|
||||
|
||||
expect(obj.visible).toBe(true);
|
||||
expect(obj.alpha).toBe(0);
|
||||
expect(testgame.baseview.animations.simulate(obj, 'alpha')).toEqual([0, 0.25, 0.5, 0.75, 1]);
|
||||
|
||||
obj.alpha = 1;
|
||||
testgame.baseview.animations.hide(obj);
|
||||
|
||||
expect(obj.visible).toBe(true);
|
||||
expect(obj.alpha).toBe(1);
|
||||
expect(testgame.baseview.animations.simulate(obj, 'alpha')).toEqual([1, 0.75, 0.5, 0.25, 0]);
|
||||
});
|
||||
|
||||
it("animates rotation", function () {
|
||||
let obj = { rotation: -Math.PI * 2.5 };
|
||||
let tween = testgame.ui.tweens.create(obj);
|
||||
let result = Animations.rotationTween(tween, Math.PI * 0.25, 1, Phaser.Easing.Linear.None);
|
||||
expect(result).toEqual(750);
|
||||
expect(tween.generateData(4)).toEqual([
|
||||
{ rotation: -Math.PI * 0.25 },
|
||||
{ rotation: 0 },
|
||||
{ rotation: Math.PI * 0.25 },
|
||||
]);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -7,35 +7,82 @@ module TS.SpaceTac.UI {
|
|||
};
|
||||
|
||||
/**
|
||||
* Utility functions for animation
|
||||
* Interface of an object that may be shown/hidden, with opacity transition.
|
||||
*/
|
||||
export class Animation {
|
||||
interface IAnimationFadeable {
|
||||
alpha: number;
|
||||
visible: boolean;
|
||||
}
|
||||
|
||||
// Display an object, fading in using opacity
|
||||
static fadeIn(game: Phaser.Game, obj: PIXI.DisplayObject, duration: number = 1000, alpha: number = 1): void {
|
||||
/**
|
||||
* Manager of all animations.
|
||||
*
|
||||
* This is a wrapper around phaser's tweens.
|
||||
*/
|
||||
export class Animations {
|
||||
private tweens: Phaser.TweenManager;
|
||||
|
||||
constructor(tweens: Phaser.TweenManager) {
|
||||
this.tweens = tweens;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a tween on an object.
|
||||
*
|
||||
* If a previous tween is running for this object, it will be stopped, and a new one will be created.
|
||||
*/
|
||||
private createTween(obj: any): Phaser.Tween {
|
||||
this.tweens.removeFrom(obj);
|
||||
let result = this.tweens.create(obj);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate the tween currently applied to an object's property
|
||||
*
|
||||
* This may be heavy work and should only be done in testing code.
|
||||
*/
|
||||
simulate(obj: any, property: string, points = 5, duration = 1000): number[] {
|
||||
let tween = first(this.tweens.getAll().concat((<any>this.tweens)._add), tween => tween.target === obj && !tween.pendingDelete);
|
||||
if (tween) {
|
||||
return [obj[property]].concat(tween.generateData(points - 1).map(data => data[property]));
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display an object, with opacity transition
|
||||
*/
|
||||
show(obj: IAnimationFadeable, duration = 1000, alpha = 1): void {
|
||||
if (!obj.visible) {
|
||||
obj.alpha = 0;
|
||||
obj.visible = true;
|
||||
}
|
||||
var tween = game.tweens.create(obj);
|
||||
|
||||
let tween = this.createTween(obj);
|
||||
tween.to({ alpha: alpha }, duration);
|
||||
tween.start();
|
||||
}
|
||||
|
||||
// Hide an object, fading out using opacity
|
||||
static fadeOut(game: Phaser.Game, obj: PIXI.DisplayObject, duration: number = 1000): void {
|
||||
var tween = game.tweens.create(obj);
|
||||
/**
|
||||
* Hide an object, with opacity transition
|
||||
*/
|
||||
hide(obj: IAnimationFadeable, duration = 1000): void {
|
||||
let tween = this.createTween(obj);
|
||||
tween.to({ alpha: 0 }, duration);
|
||||
tween.onComplete.addOnce(() => obj.visible = false);
|
||||
tween.start();
|
||||
}
|
||||
|
||||
// Set visibility of an object, using either fadeIn or fadeOut
|
||||
static setVisibility(game: Phaser.Game, obj: PIXI.DisplayObject, visible: boolean, duration: number = 1000): void {
|
||||
/**
|
||||
* Set an object visibility, with opacity transition
|
||||
*/
|
||||
setVisible(obj: IAnimationFadeable, visible: boolean, duration = 1000): void {
|
||||
if (visible) {
|
||||
Animation.fadeIn(game, obj, duration);
|
||||
this.show(obj, duration);
|
||||
} else {
|
||||
Animation.fadeOut(game, obj, duration);
|
||||
this.hide(obj, duration);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +124,7 @@ module TS.SpaceTac.UI {
|
|||
static moveInSpace(obj: PhaserGraphics, x: number, y: number, angle: number, rotated_obj = obj): number {
|
||||
if (x == obj.x && y == obj.y) {
|
||||
let tween = obj.game.tweens.create(rotated_obj);
|
||||
let duration = Animation.rotationTween(tween, angle, 0.3);
|
||||
let duration = Animations.rotationTween(tween, angle, 0.3);
|
||||
tween.start();
|
||||
return duration;
|
||||
} else {
|
|
@ -116,7 +116,7 @@ module TS.SpaceTac.UI {
|
|||
|
||||
// LOD
|
||||
let detailed = focus && level == 2;
|
||||
this.children.forEach(child => Animation.setVisibility(this.game, child, detailed, 300));
|
||||
this.children.forEach(child => this.view.animations.setVisible(child, detailed, 300));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,9 +128,9 @@ module TS.SpaceTac.UI {
|
|||
let angle = Math.atan2(location.y, location.x);
|
||||
this.button_jump.scale.set(location.star.radius * 0.002, location.star.radius * 0.002);
|
||||
this.button_jump.position.set(location.star.x + location.x + 0.02 * Math.cos(angle), location.star.y + location.y + 0.02 * Math.sin(angle));
|
||||
Animation.setVisibility(this.game, this.button_jump, true, 300);
|
||||
this.animations.setVisible(this.button_jump, true, 300);
|
||||
} else {
|
||||
Animation.setVisibility(this.game, this.button_jump, false, 300);
|
||||
this.animations.setVisible(this.button_jump, false, 300);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,7 +180,7 @@ module TS.SpaceTac.UI {
|
|||
*/
|
||||
doJump() {
|
||||
if (this.player.fleet.location && this.player.fleet.location.type == StarLocationType.WARP && this.player.fleet.location.jump_dest) {
|
||||
Animation.setVisibility(this.game, this.button_jump, false, 300);
|
||||
this.animations.setVisible(this.button_jump, false, 300);
|
||||
|
||||
let dest_location = this.player.fleet.location.jump_dest;
|
||||
let dest_star = dest_location.star;
|
||||
|
|
Loading…
Reference in a new issue