arena: Display hud info on value change
This commit is contained in:
parent
9de1ebcad2
commit
a1f005c609
3
TODO
3
TODO
|
@ -18,8 +18,7 @@
|
|||
* Menu: allow to delete cloud saves
|
||||
* Arena: hide dead drones from tactical view
|
||||
* Arena: add power indicator in ship hover information
|
||||
* Arena: temporarily show ship information when it changes
|
||||
* Arena: display important changes (damages, effects...) instead of attribute changes
|
||||
* Arena: display effects description instead of attribute changes
|
||||
* Arena: Organize objects and information in layers
|
||||
* Arena: Add auto-move to attack
|
||||
* Actions: Separate overheat and cooldown display
|
||||
|
|
|
@ -25,6 +25,13 @@ module TS.SpaceTac {
|
|||
return this.current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the maximal value
|
||||
*/
|
||||
getMaximal(): number | null {
|
||||
return this.maximal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the upper bound the value must not cross
|
||||
*/
|
||||
|
|
|
@ -126,6 +126,7 @@ module TS.SpaceTac.UI {
|
|||
var arena_ship = this.findShipSprite(ship);
|
||||
if (arena_ship) {
|
||||
arena_ship.setHovered(true);
|
||||
this.bringToTop(arena_ship);
|
||||
}
|
||||
this.hovered = arena_ship;
|
||||
} else {
|
||||
|
|
|
@ -23,6 +23,7 @@ module TS.SpaceTac.UI {
|
|||
info: Phaser.Group
|
||||
info_hull: ValueBar
|
||||
info_shield: ValueBar
|
||||
info_toggle: Toggle
|
||||
|
||||
// Frame to indicate the owner of the ship, and if it is playing
|
||||
frame: Phaser.Image
|
||||
|
@ -74,6 +75,7 @@ module TS.SpaceTac.UI {
|
|||
this.info_shield.setValue(this.ship.getValue("shield"), this.ship.getAttribute("shield_capacity"));
|
||||
this.info.add(this.info_shield);
|
||||
this.info.visible = false;
|
||||
this.info_toggle = this.battleview.animations.newVisibilityToggle(this.info, 200);
|
||||
this.add(this.info);
|
||||
|
||||
// Effects display
|
||||
|
@ -93,11 +95,28 @@ module TS.SpaceTac.UI {
|
|||
this.position.set(ship.arena_x, ship.arena_y);
|
||||
|
||||
// Log processing
|
||||
this.battleview.log_processor.registerForShip(ship, event => {
|
||||
if (event instanceof EffectAddedEvent || event instanceof EffectRemovedEvent || event instanceof EffectDurationChangedEvent) {
|
||||
this.updateStickyEffects();
|
||||
this.battleview.log_processor.registerForShip(ship, event => this.processLogEvent(event));
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a log event for this ship
|
||||
*/
|
||||
private processLogEvent(event: BaseLogEvent) {
|
||||
if (event instanceof EffectAddedEvent || event instanceof EffectRemovedEvent || event instanceof EffectDurationChangedEvent) {
|
||||
this.updateStickyEffects();
|
||||
} else if (event instanceof ValueChangeEvent) {
|
||||
if (event.value.name == "hull") {
|
||||
this.info_toggle.start(1500, true);
|
||||
this.info_hull.setValue(event.value.get(), event.value.getMaximal() || 0);
|
||||
} else if (event.value.name == "shield") {
|
||||
this.info_toggle.start(1500, true);
|
||||
this.info_shield.setValue(event.value.get(), event.value.getMaximal() || 0);
|
||||
} else {
|
||||
this.displayValueChanged(event);
|
||||
}
|
||||
});
|
||||
} else if (event instanceof DamageEvent) {
|
||||
this.displayEffect(`${event.hull + event.shield} damage`, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -106,7 +125,11 @@ module TS.SpaceTac.UI {
|
|||
* This will show the information HUD accordingly
|
||||
*/
|
||||
setHovered(hovered: boolean) {
|
||||
this.battleview.animations.setVisible(this.info, hovered, 200);
|
||||
if (hovered) {
|
||||
this.info_toggle.start();
|
||||
} else {
|
||||
this.info_toggle.stop();
|
||||
}
|
||||
}
|
||||
|
||||
// Set the playing state on this ship
|
||||
|
@ -177,12 +200,6 @@ module TS.SpaceTac.UI {
|
|||
let diff = event.diff;
|
||||
let name = event.value.name;
|
||||
this.displayEffect(`${name} ${diff < 0 ? "-" : "+"}${Math.abs(diff)}`, diff >= 0);
|
||||
|
||||
if (name == "hull") {
|
||||
this.info_hull.setValue(event.value.get(), this.ship.getAttribute("hull_capacity"));
|
||||
} else if (name == "shield") {
|
||||
this.info_shield.setValue(event.value.get(), this.ship.getAttribute("shield_capacity"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -100,8 +100,6 @@ module TS.SpaceTac.UI {
|
|||
this.processShipChangeEvent(event);
|
||||
} else if (event instanceof MoveEvent) {
|
||||
this.processMoveEvent(event);
|
||||
} else if (event instanceof ValueChangeEvent) {
|
||||
this.processValueChangedEvent(event);
|
||||
} else if (event instanceof DeathEvent) {
|
||||
this.processDeathEvent(event);
|
||||
} else if (event instanceof FireEvent) {
|
||||
|
@ -170,16 +168,6 @@ module TS.SpaceTac.UI {
|
|||
}
|
||||
}
|
||||
|
||||
// Ship value changed
|
||||
private processValueChangedEvent(event: ValueChangeEvent): void {
|
||||
var sprite = this.view.arena.findShipSprite(event.ship);
|
||||
if (sprite) {
|
||||
sprite.displayValueChanged(event);
|
||||
}
|
||||
|
||||
// TODO Update tooltip
|
||||
}
|
||||
|
||||
// A ship died
|
||||
private processDeathEvent(event: DeathEvent): void {
|
||||
if (this.view.ship_hovered === event.ship) {
|
||||
|
|
|
@ -102,6 +102,13 @@ module TS.SpaceTac.UI {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a toggle on visibility
|
||||
*/
|
||||
newVisibilityToggle(obj: IAnimationFadeable, duration = 1000): Toggle {
|
||||
return new Toggle(() => this.setVisible(obj, true, duration), () => this.setVisible(obj, false, duration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Interpolate a rotation value
|
||||
*
|
||||
|
|
107
src/ui/common/Toggle.spec.ts
Normal file
107
src/ui/common/Toggle.spec.ts
Normal file
|
@ -0,0 +1,107 @@
|
|||
/// <reference path="../TestGame.ts"/>
|
||||
|
||||
module TS.SpaceTac.UI.Specs {
|
||||
describe("Toggle", function () {
|
||||
let on_calls = 0;
|
||||
let off_calls = 0;
|
||||
|
||||
beforeEach(function () {
|
||||
on_calls = 0;
|
||||
off_calls = 0;
|
||||
jasmine.clock().install();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
function newToggle(): Toggle {
|
||||
return new Toggle(() => on_calls++, () => off_calls++);
|
||||
}
|
||||
|
||||
function check(on: number, off: number) {
|
||||
expect(on_calls).toBe(on);
|
||||
expect(off_calls).toBe(off);
|
||||
on_calls = 0;
|
||||
off_calls = 0;
|
||||
}
|
||||
|
||||
it("handles simple toggling", function () {
|
||||
let toggle = newToggle();
|
||||
check(0, 0);
|
||||
|
||||
toggle.start();
|
||||
check(1, 0);
|
||||
|
||||
jasmine.clock().tick(10000000);
|
||||
check(0, 0);
|
||||
|
||||
toggle.stop();
|
||||
check(0, 1);
|
||||
|
||||
jasmine.clock().tick(10000000);
|
||||
check(0, 0);
|
||||
|
||||
toggle.stop();
|
||||
check(0, 0);
|
||||
|
||||
toggle.start();
|
||||
check(1, 0);
|
||||
});
|
||||
|
||||
it("applies hard priority", function () {
|
||||
let toggle = newToggle();
|
||||
check(0, 0);
|
||||
|
||||
// hard
|
||||
toggle.start(0, true);
|
||||
check(1, 0);
|
||||
|
||||
toggle.stop(false);
|
||||
check(0, 0);
|
||||
|
||||
toggle.stop(true);
|
||||
check(0, 1);
|
||||
|
||||
// soft
|
||||
toggle.start(0, false);
|
||||
check(1, 0);
|
||||
|
||||
toggle.stop(true);
|
||||
check(0, 1);
|
||||
|
||||
// soft lifted to hard
|
||||
toggle.start(0, false);
|
||||
check(1, 0);
|
||||
|
||||
toggle.start(0, true);
|
||||
check(0, 0);
|
||||
|
||||
toggle.stop(false);
|
||||
check(0, 0);
|
||||
|
||||
toggle.stop(true);
|
||||
check(0, 1);
|
||||
});
|
||||
|
||||
it("automatically stop after a duration", function () {
|
||||
let toggle = newToggle();
|
||||
check(0, 0);
|
||||
|
||||
toggle.start(10);
|
||||
check(1, 0);
|
||||
|
||||
jasmine.clock().tick(9);
|
||||
check(0, 0);
|
||||
|
||||
jasmine.clock().tick(2);
|
||||
check(0, 1);
|
||||
|
||||
toggle.stop();
|
||||
check(0, 0);
|
||||
|
||||
toggle.start();
|
||||
check(1, 0);
|
||||
});
|
||||
});
|
||||
}
|
50
src/ui/common/Toggle.ts
Normal file
50
src/ui/common/Toggle.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
module TS.SpaceTac {
|
||||
/**
|
||||
* A toggle between two states (on and off), with timing features.
|
||||
*/
|
||||
export class Toggle {
|
||||
private on: Function
|
||||
private off: Function
|
||||
private status = false
|
||||
private hard = false
|
||||
private timer = Timer.global;
|
||||
|
||||
constructor(on: Function, off: Function) {
|
||||
this.on = on;
|
||||
this.off = off;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the toggle (set the status *on*)
|
||||
*
|
||||
* If *duration* is set, stop() will automatically be called after these milliseconds.
|
||||
*
|
||||
* If *hard* is true, it can only be stopped by a hard stop.
|
||||
*/
|
||||
start(duration = 0, hard = false) {
|
||||
if (hard) {
|
||||
this.hard = true;
|
||||
}
|
||||
if (!this.status) {
|
||||
this.status = true;
|
||||
this.on();
|
||||
}
|
||||
if (duration) {
|
||||
this.timer.schedule(duration, () => this.stop(hard));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the toggle (set the status *off*)
|
||||
*/
|
||||
stop(hard = false) {
|
||||
if (this.status) {
|
||||
if (hard || !this.hard) {
|
||||
this.status = false;
|
||||
this.hard = false;
|
||||
this.off();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue