1
0
Fork 0
spacetac/src/ui/battle/Arena.ts

264 lines
8.7 KiB
TypeScript
Raw Normal View History

2017-02-09 00:00:35 +00:00
module TS.SpaceTac.UI {
2017-05-17 21:55:39 +00:00
/**
* 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
2017-05-17 21:55:39 +00:00
battleview: BattleView
2017-05-17 21:55:39 +00:00
// Boundaries of the arena
boundaries: IBounded = { x: 112, y: 132, width: 1808, height: 948 }
2015-03-03 00:00:00 +00:00
// Hint for weapon or move range
2017-05-17 21:55:39 +00:00
range_hint: RangeHint
// Input capture
private mouse_capture: Phaser.Button
2015-03-03 00:00:00 +00:00
// Input callback to receive mouse move events
2017-05-17 21:55:39 +00:00
private input_callback: any = null
// List of ship sprites
2017-05-17 21:55:39 +00:00
private ship_sprites: ArenaShip[] = []
2017-02-08 18:54:02 +00:00
// List of drone sprites
2017-05-17 21:55:39 +00:00
private drone_sprites: ArenaDrone[] = []
// Currently hovered ship
2017-05-17 21:55:39 +00:00
private hovered: ArenaShip | null
// Currently playing ship
2017-05-17 21:55:39 +00:00
private playing: ArenaShip | null
// Layer for particles
2017-05-17 21:55:39 +00:00
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) {
2016-10-26 21:15:04 +00:00
super(battleview.game);
this.battleview = battleview;
this.playing = null;
this.hovered = null;
2017-03-09 17:11:00 +00:00
this.range_hint = new RangeHint(this);
2017-05-17 21:55:39 +00:00
this.position.set(this.boundaries.x, this.boundaries.y);
this.init();
}
/**
* Setup the mouse capture for targetting events
*/
setupMouseCapture() {
let battleview = this.battleview;
2015-01-23 00:00:00 +00:00
var background = new Phaser.Button(battleview.game, 0, 0, "battle-arena-background");
2017-05-17 21:55:39 +00:00
background.scale.set(this.boundaries.width / background.width, this.boundaries.height / background.height);
this.mouse_capture = background;
// Capture clicks on background
background.onInputUp.add(() => {
battleview.cursorClicked();
});
// Watch mouse move to capture hovering over background
this.input_callback = this.game.input.addMoveCallback((pointer: Phaser.Pointer) => {
var point = new Phaser.Point();
if (battleview.game.input.hitTest(background, pointer, point)) {
battleview.cursorInSpace(point.x * background.scale.x, point.y * background.scale.y);
}
}, null);
2017-05-17 21:55:39 +00:00
this.add(this.mouse_capture);
}
destroy() {
2017-05-17 21:55:39 +00:00
if (this.input_callback) {
this.game.input.deleteMoveCallback(this.input_callback);
this.input_callback = null;
}
super.destroy();
}
2017-05-17 21:55:39 +00:00
/**
* Initialize state (create sprites)
*/
init(): void {
2017-05-17 21:55:39 +00:00
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);
});
}
2017-02-09 00:00:35 +00:00
// Get the current MainUI instance
getGame(): MainUI {
return this.battleview.gameui;
}
2017-05-09 20:41:35 +00:00
/**
* Get the current battle displayed
*/
getBattle(): Battle {
return this.battleview.battle;
}
2015-02-18 00:00:00 +00:00
// Remove a ship sprite
2017-02-09 00:00:35 +00:00
markAsDead(ship: Ship): void {
2015-02-18 00:00:00 +00:00
var sprite = this.findShipSprite(ship);
if (sprite) {
2017-02-15 22:34:27 +00:00
sprite.setDead(true);
2017-05-17 23:24:42 +00:00
this.layer_garbage.add(sprite);
2015-02-18 00:00:00 +00:00
}
}
// Find the sprite for a ship
2017-03-09 17:11:00 +00:00
findShipSprite(ship: Ship): ArenaShip | null {
var result: ArenaShip | null = null;
this.ship_sprites.forEach((sprite: ArenaShip) => {
if (sprite.ship === ship) {
result = sprite;
}
});
return result;
}
// Set the hovered state on a ship sprite
2017-03-09 17:11:00 +00:00
setShipHovered(ship: Ship | null): void {
if (this.hovered) {
this.hovered.setHovered(false);
}
2017-03-09 17:11:00 +00:00
if (ship) {
var arena_ship = this.findShipSprite(ship);
if (arena_ship) {
arena_ship.setHovered(true);
2017-05-17 21:55:39 +00:00
this.layer_ships.bringToTop(arena_ship);
2017-03-09 17:11:00 +00:00
}
this.hovered = arena_ship;
} else {
this.hovered = null;
}
}
// Set the playing state on a ship sprite
2017-03-09 17:11:00 +00:00
setShipPlaying(ship: Ship | null): void {
if (this.playing) {
this.playing.setPlaying(false);
2017-03-09 17:11:00 +00:00
this.playing = null;
}
2017-03-09 17:11:00 +00:00
if (ship) {
var arena_ship = this.findShipSprite(ship);
if (arena_ship) {
2017-05-17 21:55:39 +00:00
this.layer_ships.bringToTop(arena_ship);
2017-03-09 17:11:00 +00:00
arena_ship.setPlaying(true);
}
this.playing = arena_ship;
}
}
2017-02-08 18:54:02 +00:00
/**
* Find an ArenaDrone displaying a Drone.
*/
findDrone(drone: Drone): ArenaDrone | null {
return first(this.drone_sprites, sprite => sprite.drone == drone);
}
/**
* Spawn a new drone
*
* Return the duration of deploy animation
*/
addDrone(drone: Drone, animate = true): number {
if (!this.findDrone(drone)) {
2017-02-08 18:54:02 +00:00
let sprite = new ArenaDrone(this.battleview, drone);
let angle = Math.atan2(drone.y - drone.owner.arena_y, drone.x - drone.owner.arena_x);
2017-05-17 21:55:39 +00:00
this.layer_drones.add(sprite);
2017-02-08 18:54:02 +00:00
this.drone_sprites.push(sprite);
if (animate) {
sprite.position.set(drone.owner.arena_x, drone.owner.arena_y);
2017-05-22 23:05:01 +00:00
sprite.sprite.rotation = drone.owner.arena_angle;
let move_duration = Animations.moveInSpace(sprite, drone.x, drone.y, angle, sprite.sprite);
this.game.tweens.create(sprite.radius).from({ alpha: 0 }, 500, Phaser.Easing.Cubic.In, true, move_duration);
return move_duration + 500;
} else {
sprite.position.set(drone.x, drone.y);
2017-05-22 23:05:01 +00:00
sprite.sprite.rotation = angle;
return 0;
}
2017-02-08 18:54:02 +00:00
} else {
console.error("Drone added twice to arena", drone);
return 0;
2017-02-08 18:54:02 +00:00
}
}
2017-05-10 23:13:56 +00:00
/**
* Remove a destroyed drone
*/
2017-02-09 00:00:35 +00:00
removeDrone(drone: Drone): void {
let sprite = this.findDrone(drone);
2017-02-08 18:54:02 +00:00
if (sprite) {
remove(this.drone_sprites, sprite);
2017-05-10 23:13:56 +00:00
sprite.setDestroyed();
2017-05-17 21:55:39 +00:00
this.layer_garbage.add(sprite);
2017-02-08 18:54:02 +00:00
} else {
console.error("Drone not found in arena for removal", drone);
}
}
/**
* Highlight ships that would be the target of current action
*/
highlightTargets(ships: Ship[]): void {
this.ship_sprites.forEach(sprite => sprite.setTargetted(contains(ships, sprite.ship)));
}
2017-05-15 18:30:44 +00:00
/**
* Switch the tactical mode (shows information on all ships, and fades background)
2017-05-15 18:30:44 +00:00
*/
setTacticalMode(active: boolean): void {
2017-05-15 18:30:44 +00:00
this.ship_sprites.forEach(sprite => sprite.setHovered(active));
this.drone_sprites.forEach(drone => drone.setTacticalMode(active));
2017-05-17 21:55:39 +00:00
this.battleview.animations.setVisible(this.layer_garbage, !active, 200);
2017-05-15 18:30:44 +00:00
if (this.battleview.background) {
this.battleview.animations.setVisible(this.battleview.background, !active, 200);
}
}
2017-05-16 23:12:05 +00:00
/**
* Get the boundaries of the arena on display
*/
getBoundaries(): IBounded {
return { x: 130, y: 140, width: 1920 - 138, height: 1080 - 148 };
}
}
}