1
0
Fork 0

arena: Reorganize in layers

This commit is contained in:
Michaël Lemaire 2017-05-17 23:55:39 +02:00
parent a1f005c609
commit a3df49ae0b
6 changed files with 89 additions and 59 deletions

20
TODO
View file

@ -1,4 +1,4 @@
* UI: Use a common component class, and a layer abstraction
* UI: use a common component class, and a layer abstraction
* Character sheet: add initial character creation
* Character sheet: disable interaction during battle (except for loot screen)
* Character sheet: improve eye-catching for shop and loot section
@ -16,22 +16,20 @@
* Equipment: add area effects, without the need of activation/stickyness (eg. damage reduction, attribute modifier...)
* Menu: end appear animation when a button is clicked
* Menu: allow to delete cloud saves
* Arena: hide dead drones from tactical view
* Arena: add power indicator in ship hover information
* 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
* Actions: Show power usage/recovery in power bar, on action hover
* Actions: Fix targetting not resetting when using keyboard shortcuts
* Arena: add auto-move to attack
* Actions: separate overheat and cooldown display
* Actions: show power usage/recovery in power bar, on action hover
* Actions: fix targetting not resetting when using keyboard shortcuts
* Suspend AI operation when the game is paused (window not focused)
* Add permanent effects to ship models to ease balancing
* Find incentives to move from starting position
* Outcome: Add battle statistics and/or honors
* Outcome: Disable the loot button if there is no loot
* Outcome: add battle statistics and/or honors
* Outcome: disable the loot button if there is no loot
* Ensure that tweens and particle emitters get destroyed once animation is done (or view changes)
* Controls: Do not focus on ship while targetting for area effects (dissociate hover and target)
* Controls: Fix hover being stuck when the cursor exits the window
* Controls: do not focus on ship while targetting for area effects (dissociate hover and target)
* Controls: fix hover being stuck when the cursor exits the window
* Drones: add hull points and take area damage
* Drones: find a way to avoid arena cluttering
* Add a battle log display

View file

@ -1,32 +1,43 @@
module TS.SpaceTac.UI {
// Graphical representation of a battle
// This is the area in the BattleView that will display ships with their real positions
/**
* Graphical representation of a battle
*
* This is the area in the BattleView that will display ships with their real positions
*/
export class Arena extends Phaser.Group {
// Link to battleview
battleview: BattleView;
battleview: BattleView
// Arena background
background: Phaser.Button;
// Boundaries of the arena
boundaries: IBounded = { x: 112, y: 132, width: 1808, height: 948 }
// Hint for weapon or move range
range_hint: RangeHint;
range_hint: RangeHint
// Input capture
private mouse_capture: Phaser.Button
// Input callback to receive mouse move events
private input_callback: any;
private input_callback: any = null
// List of ship sprites
private ship_sprites: ArenaShip[] = [];
private ship_sprites: ArenaShip[] = []
// List of drone sprites
private drone_sprites: ArenaDrone[] = [];
private drone_sprites: ArenaDrone[] = []
// Currently hovered ship
private hovered: ArenaShip | null;
private hovered: ArenaShip | null
// Currently playing ship
private playing: ArenaShip | null;
private playing: ArenaShip | null
// Layer for particles
layer_weapon_effects: Phaser.Group;
layer_garbage: Phaser.Group
layer_hints: Phaser.Group
layer_drones: Phaser.Group
layer_ships: Phaser.Group
layer_weapon_effects: Phaser.Group
layer_targetting: Phaser.Group
// Create a graphical arena for ship sprites to fight in a 2D space
constructor(battleview: BattleView) {
@ -37,14 +48,20 @@ module TS.SpaceTac.UI {
this.hovered = null;
this.range_hint = new RangeHint(this);
var offset_x = 112;
var offset_y = 132;
this.position.set(this.boundaries.x, this.boundaries.y);
this.init();
}
/**
* Setup the mouse capture for targetting events
*/
setupMouseCapture() {
let battleview = this.battleview;
var background = new Phaser.Button(battleview.game, 0, 0, "battle-arena-background");
var expected_width = battleview.getWidth() - offset_x;
var expected_height = battleview.getHeight() - offset_y;
background.scale.set(expected_width / background.width, expected_height / background.height);
this.background = background;
background.scale.set(this.boundaries.width / background.width, this.boundaries.height / background.height);
this.mouse_capture = background;
// Capture clicks on background
background.onInputUp.add(() => {
@ -59,30 +76,43 @@ module TS.SpaceTac.UI {
}
}, null);
this.position.set(offset_x, offset_y);
this.add(this.background);
this.add(this.range_hint);
this.init();
this.add(this.mouse_capture);
}
destroy() {
this.game.input.deleteMoveCallback(this.input_callback);
if (this.input_callback) {
this.game.input.deleteMoveCallback(this.input_callback);
this.input_callback = null;
}
super.destroy();
}
// Initialize state (create sprites)
/**
* Initialize state (create sprites)
*/
init(): void {
// Add ship sprites
this.battleview.battle.play_order.forEach(ship => {
var sprite = new ArenaShip(this, ship);
this.add(sprite);
this.setupMouseCapture();
this.layer_garbage = this.add(new Phaser.Group(this.game));
this.layer_hints = this.add(new Phaser.Group(this.game));
this.layer_drones = this.add(new Phaser.Group(this.game));
this.layer_ships = this.add(new Phaser.Group(this.game));
this.layer_weapon_effects = this.add(new Phaser.Group(this.game));
this.layer_targetting = this.add(new Phaser.Group(this.game));
this.layer_hints.add(this.range_hint);
this.addShipSprites();
}
/**
* Add the sprites for all ships
*/
addShipSprites() {
iforeach(this.battleview.battle.iships(), ship => {
let sprite = new ArenaShip(this, ship);
this.layer_ships.add(sprite);
this.ship_sprites.push(sprite);
});
this.layer_weapon_effects = new Phaser.Group(this.game);
this.add(this.layer_weapon_effects);
}
// Get the current MainUI instance
@ -126,7 +156,7 @@ module TS.SpaceTac.UI {
var arena_ship = this.findShipSprite(ship);
if (arena_ship) {
arena_ship.setHovered(true);
this.bringToTop(arena_ship);
this.layer_ships.bringToTop(arena_ship);
}
this.hovered = arena_ship;
} else {
@ -144,7 +174,7 @@ module TS.SpaceTac.UI {
if (ship) {
var arena_ship = this.findShipSprite(ship);
if (arena_ship) {
this.bringToTop(arena_ship);
this.layer_ships.bringToTop(arena_ship);
arena_ship.setPlaying(true);
}
this.playing = arena_ship;
@ -167,7 +197,7 @@ module TS.SpaceTac.UI {
if (!this.findDrone(drone)) {
let sprite = new ArenaDrone(this.battleview, drone);
let angle = Math.atan2(drone.y - drone.owner.arena_y, drone.x - drone.owner.arena_x);
this.add(sprite);
this.layer_drones.add(sprite);
this.drone_sprites.push(sprite);
if (animate) {
@ -197,6 +227,7 @@ module TS.SpaceTac.UI {
if (sprite) {
remove(this.drone_sprites, sprite);
sprite.setDestroyed();
this.layer_garbage.add(sprite);
} else {
console.error("Drone not found in arena for removal", drone);
}
@ -214,6 +245,7 @@ module TS.SpaceTac.UI {
*/
setTacticalMode(active: boolean): void {
this.ship_sprites.forEach(sprite => sprite.setHovered(active));
this.battleview.animations.setVisible(this.layer_garbage, !active, 200);
if (this.battleview.background) {
this.battleview.animations.setVisible(this.battleview.background, !active, 200);
}

View file

@ -2,6 +2,7 @@ module TS.SpaceTac.UI {
// Ship sprite in the arena (BattleView)
export class ArenaShip extends Phaser.Group {
// Link to the view
arena: Arena
battleview: BattleView
// Link to displayed ship
@ -35,6 +36,7 @@ module TS.SpaceTac.UI {
// Create a ship sprite usable in the Arena
constructor(parent: Arena, ship: Ship) {
super(parent.game);
this.arena = parent;
this.battleview = parent.battleview;
this.ship = ship;

View file

@ -11,7 +11,7 @@ module TS.SpaceTac.UI {
primary: Phaser.Circle | null;
constructor(parent: Arena) {
super(parent.game, parent);
super(parent.game);
this.parent = parent;

View file

@ -28,8 +28,6 @@ module TS.SpaceTac.UI.Specs {
let source = new Phaser.Group(battleview.game, battleview.arena);
source.position.set(0, 0);
let init_children = battleview.arena.children.length;
let targetting = new Targetting(battleview);
targetting.setSource(source);
@ -38,12 +36,12 @@ module TS.SpaceTac.UI.Specs {
targetting.updateApIndicators();
expect(targetting.ap_indicators.length).toBe(0);
expect(battleview.arena.children.length).toBe(init_children + 3);
expect(battleview.arena.layer_targetting.children.length).toBe(3);
targetting.setApIndicatorsInterval(Math.sqrt(5) * 20);
expect(targetting.ap_indicators.length).toBe(5);
expect(battleview.arena.children.length).toBe(init_children + 3 + 5);
expect(battleview.arena.layer_targetting.children.length).toBe(3 + 5);
expect(targetting.ap_indicators[0].position.x).toBe(0);
expect(targetting.ap_indicators[0].position.y).toBe(0);
expect(targetting.ap_indicators[1].position.x).toBeCloseTo(40);
@ -57,15 +55,15 @@ module TS.SpaceTac.UI.Specs {
targetting.setApIndicatorsInterval(1000);
expect(targetting.ap_indicators.length).toBe(1);
expect(battleview.arena.children.length).toBe(init_children + 3 + 1);
expect(battleview.arena.layer_targetting.children.length).toBe(3 + 1);
targetting.setApIndicatorsInterval(1);
expect(targetting.ap_indicators.length).toBe(224);
expect(battleview.arena.children.length).toBe(init_children + 3 + 224);
expect(battleview.arena.layer_targetting.children.length).toBe(3 + 224);
targetting.destroy();
expect(battleview.arena.children.length).toBe(init_children);
expect(battleview.arena.layer_targetting.children.length).toBe(0);
});
});
}

View file

@ -41,13 +41,13 @@ module TS.SpaceTac.UI {
this.blast = new Phaser.Image(battleview.game, 0, 0, "battle-arena-blast");
this.blast.anchor.set(0.5, 0.5);
this.blast.visible = false;
battleview.arena.add(this.blast);
battleview.arena.layer_targetting.add(this.blast);
this.line_initial = new Phaser.Graphics(battleview.game, 0, 0);
this.line_initial.visible = false;
battleview.arena.add(this.line_initial);
battleview.arena.layer_targetting.add(this.line_initial);
this.line_corrected = new Phaser.Graphics(battleview.game, 0, 0);
this.line_corrected.visible = false;
battleview.arena.add(this.line_corrected);
battleview.arena.layer_targetting.add(this.line_corrected);
}
this.source = null;
@ -138,7 +138,7 @@ module TS.SpaceTac.UI {
while (this.ap_indicators.length < count) {
let indicator = new Phaser.Image(this.battleview.game, 0, 0, "battle-arena-ap-indicator");
indicator.anchor.set(0.5, 0.5);
this.battleview.arena.addChild(indicator);
this.battleview.arena.layer_targetting.add(indicator);
this.ap_indicators.push(indicator);
}
while (this.ap_indicators.length > count) {