1
0
Fork 0

arena: Display hud info on value change

This commit is contained in:
Michaël Lemaire 2017-05-17 22:59:25 +02:00
parent 9de1ebcad2
commit a1f005c609
8 changed files with 201 additions and 25 deletions

3
TODO
View file

@ -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

View file

@ -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
*/

View file

@ -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 {

View file

@ -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"));
}
}
/**

View file

@ -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) {

View file

@ -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
*

View 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
View 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();
}
}
}
}
}