1
0
Fork 0

Added hold-to-hover mode for mobile targets

This commit is contained in:
Michaël Lemaire 2017-01-19 01:17:24 +01:00
parent 3ac51adb19
commit c2059fd35a
6 changed files with 92 additions and 31 deletions

2
TODO
View file

@ -3,7 +3,7 @@
* Re-style cancel button and allow to cancel by clicking the action again
* Add equipment info (or summary) in ship tooltip
* Handle effects overflowing ship tooltip when too numerous
* Mobile: display tooltips on hold
* Mobile: think UI layout so that fingers do not block the view (right and left handed)
* Mobile: targetting in two times, using a draggable target indicator
* Add a defeat screen (game over for now)
* Add a victory screen, with loot display

View file

@ -51,20 +51,17 @@ module SpaceTac.View {
this.layer_icon.scale.set(0.25, 0.25);
this.addChild(this.layer_icon);
// Click process
this.onInputUp.add(() => {
this.processClick();
});
// Information on hover
this.onInputOver.add(() => {
let show_info = () => {
this.bar.tooltip.setAction(this);
this.battleview.arena.range_hint.setSecondary(this.ship, this.action);
});
this.onInputOut.add(() => {
};
let hide_info = () => {
this.bar.tooltip.setAction(null);
this.battleview.arena.range_hint.clearSecondary();
});
};
// Events
Tools.setHoverClick(this, show_info, hide_info, () => this.processClick());
// Initialize
this.updateActiveStatus();

View file

@ -41,16 +41,7 @@ module SpaceTac.View {
this.addChild(this.hover);
// Handle input on ship sprite
this.sprite.input.useHandCursor = true;
this.sprite.onInputOver.add(() => {
battleview.cursorOnShip(ship);
});
this.sprite.onInputOut.add(() => {
battleview.cursorOffShip(ship);
});
this.sprite.onInputUp.add(() => {
battleview.cursorClicked();
});
Tools.setHoverClick(this.sprite, () => battleview.cursorOnShip(ship), () => battleview.cursorOffShip(ship), () => battleview.cursorClicked());
// Set location
this.position.set(ship.arena_x, ship.arena_y);

View file

@ -31,14 +31,6 @@ module SpaceTac.View {
this.ship = ship;
this.input.useHandCursor = true;
this.onInputOver.add(() => {
list.battleview.cursorOnShip(ship);
});
this.onInputOut.add(() => {
list.battleview.cursorOffShip(ship);
});
this.layer_portrait = new Phaser.Image(this.game, 8, 8, "ship-" + ship.model + "-portrait", 0);
this.layer_portrait.scale.set(0.3, 0.3);
this.addChild(this.layer_portrait);
@ -65,6 +57,8 @@ module SpaceTac.View {
this.updateAttributes();
this.updateEffects();
Tools.setHoverClick(this, () => list.battleview.cursorOnShip(ship), () => list.battleview.cursorOffShip(ship), () => list.battleview.cursorClicked());
}
// Update attributes from associated ship

View file

@ -1,6 +1,6 @@
module SpaceTac.View.Specs {
describe("Tools", () => {
it("normalizes angles", () => {
it("normalizes angles", function () {
expect(Tools.normalizeAngle(0)).toEqual(0);
expect(Tools.normalizeAngle(0.1)).toBeCloseTo(0.1, 0.000001);
expect(Tools.normalizeAngle(Math.PI)).toBeCloseTo(Math.PI, 0.000001);
@ -8,5 +8,38 @@ module SpaceTac.View.Specs {
expect(Tools.normalizeAngle(-Math.PI)).toBeCloseTo(Math.PI, 0.000001);
expect(Tools.normalizeAngle(-Math.PI - 0.5)).toBeCloseTo(Math.PI - 0.5, 0.000001);
});
ingame_it("handles hover and click on desktops and mobile targets", function (game) {
let newButton: () => [Phaser.Button, any] = () => {
var button = new Phaser.Button(game);
var funcs = {
enter: () => null,
leave: () => null,
click: () => null,
};
spyOn(funcs, "enter");
spyOn(funcs, "leave");
spyOn(funcs, "click");
Tools.setHoverClick(button, funcs.enter, funcs.leave, funcs.click, 50, 100);
return [button, funcs];
}
// Simple click on desktop
let [button, funcs] = newButton();
button.onInputOver.dispatch();
button.onInputDown.dispatch();
button.onInputUp.dispatch();
expect(funcs.enter).toHaveBeenCalledTimes(0);
expect(funcs.leave).toHaveBeenCalledTimes(0);
expect(funcs.click).toHaveBeenCalledTimes(1);
// Simple click on mobile
[button, funcs] = newButton();
button.onInputDown.dispatch();
button.onInputUp.dispatch();
expect(funcs.enter).toHaveBeenCalledTimes(0);
expect(funcs.leave).toHaveBeenCalledTimes(1);
expect(funcs.click).toHaveBeenCalledTimes(1);
});
});
}

View file

@ -2,12 +2,58 @@ module SpaceTac.View {
// Common UI tools functions
export class Tools {
/**
* Setup a hover/hold/click routine on an object
*
* This should span the bridge between desktop and mobile targets.
*/
static setHoverClick(obj: Phaser.Button, enter: Function, leave: Function, click: Function, hovertime = 300, holdtime = 600) {
let holdstart = new Date();
let enternext = null;
let hovered = false;
obj.input.useHandCursor = true;
let prevententer = () => {
if (enternext != null) {
clearTimeout(enternext);
enternext = null;
}
};
obj.onInputOver.add(() => {
enternext = setTimeout(enter, hovertime);
hovered = true;
});
obj.onInputOut.add(() => {
prevententer();
leave();
hovered = false;
});
obj.onInputDown.add(() => {
holdstart = new Date();
enternext = setTimeout(enter, holdtime);
});
obj.onInputUp.add(() => {
prevententer();
if (new Date().getTime() - holdstart.getTime() < holdtime) {
click();
}
if (!hovered) {
leave();
}
});
}
// Constraint an angle in radians the ]-pi;pi] range.
static normalizeAngle(angle: number): number {
angle = angle % (2 * Math.PI);
if (angle <= -Math.PI) {
return angle + 2 * Math.PI;
} else if (angle > Math.PI) {
} else if (angle > Math.PI) {
return angle - 2 * Math.PI;
} else {
return angle;