1
0
Fork 0
spacetac/src/ui/map/UniverseMapView.ts

258 lines
9.1 KiB
TypeScript
Raw Normal View History

/// <reference path="../BaseView.ts"/>
2017-02-09 00:00:35 +00:00
module TS.SpaceTac.UI {
/**
* Interactive map of the universe
*/
export class UniverseMapView extends BaseView {
// Displayed universe
2017-06-05 17:53:27 +00:00
universe = new Universe()
// Interacting player
2017-06-05 17:53:27 +00:00
player = new Player()
2017-03-15 21:40:19 +00:00
// Layers
2017-06-05 17:53:27 +00:00
layer_universe: Phaser.Group
layer_overlay: Phaser.Group
2017-03-15 21:40:19 +00:00
2017-01-26 00:01:31 +00:00
// Star systems
2017-06-05 17:53:27 +00:00
starsystems: StarSystemDisplay[] = []
// Links between stars
starlinks_group: Phaser.Group
starlinks: Phaser.Graphics[] = []
2015-03-24 00:00:00 +00:00
2017-01-30 00:40:33 +00:00
// Fleets
2017-06-05 17:53:27 +00:00
player_fleet: FleetDisplay
2017-01-30 00:40:33 +00:00
2017-03-15 23:45:52 +00:00
// Frame to highlight current location
2017-06-05 17:53:27 +00:00
current_location: CurrentLocationMarker
2017-03-15 23:45:52 +00:00
2017-06-05 22:05:34 +00:00
// Actions for selected location
actions: MapLocationMenu
2017-02-28 00:07:37 +00:00
// Character sheet
2017-06-05 17:53:27 +00:00
character_sheet: CharacterSheet
2017-02-28 00:07:37 +00:00
2017-01-26 00:01:31 +00:00
// Zoom level
2017-06-05 17:53:27 +00:00
zoom = 0
2017-06-05 22:05:34 +00:00
zoom_in: Phaser.Button
zoom_out: Phaser.Button
/**
* Init the view, binding it to a universe
*/
2017-02-09 00:00:35 +00:00
init(universe: Universe, player: Player) {
super.init();
this.universe = universe;
this.player = player;
}
/**
* Create view graphics
*/
create() {
super.create();
this.layer_universe = this.addLayer("universe");
this.layer_overlay = this.addLayer("overlay");
2017-06-05 17:53:27 +00:00
this.starlinks_group = this.game.add.group(this.layer_universe);
2017-01-26 23:01:04 +00:00
this.starlinks = this.universe.starlinks.map(starlink => {
let loc1 = starlink.first.getWarpLocationTo(starlink.second);
let loc2 = starlink.second.getWarpLocationTo(starlink.first);
let result = new Phaser.Graphics(this.game);
2017-03-09 17:11:00 +00:00
if (loc1 && loc2) {
2017-06-05 17:53:27 +00:00
result.lineStyle(0.01, 0x6cc7ce);
2017-03-09 17:11:00 +00:00
result.moveTo(starlink.first.x - 0.5 + loc1.x, starlink.first.y - 0.5 + loc1.y);
result.lineTo(starlink.second.x - 0.5 + loc2.x, starlink.second.y - 0.5 + loc2.y);
}
result.data.link = starlink;
2017-01-26 23:01:04 +00:00
return result;
});
2017-06-05 17:53:27 +00:00
this.starlinks.forEach(starlink => this.starlinks_group.add(starlink));
2017-01-26 23:01:04 +00:00
2017-01-30 00:40:33 +00:00
this.player_fleet = new FleetDisplay(this, this.player.fleet);
2017-01-26 00:01:31 +00:00
this.starsystems = this.universe.stars.map(star => new StarSystemDisplay(this, star));
2017-03-15 21:40:19 +00:00
this.starsystems.forEach(starsystem => this.layer_universe.add(starsystem));
2017-03-15 21:40:19 +00:00
this.layer_universe.add(this.player_fleet);
2017-01-30 00:40:33 +00:00
2017-03-15 23:45:52 +00:00
this.current_location = new CurrentLocationMarker(this, this.player_fleet);
this.layer_universe.add(this.current_location);
2017-06-05 22:05:34 +00:00
this.actions = new MapLocationMenu(this);
this.actions.setPosition(30, 30);
this.actions.moveToLayer(this.layer_overlay);
this.zoom_in = new Phaser.Button(this.game, 1520, 100, "map-button-zoom", () => this.setZoom(this.zoom + 1), undefined, 1, 0);
this.zoom_in.anchor.set(0.5, 0.5);
this.layer_overlay.add(this.zoom_in);
this.tooltip.bindStaticText(this.zoom_in, "Zoom in");
this.zoom_out = new Phaser.Button(this.game, 1520, 980, "map-button-zoom", () => this.setZoom(this.zoom - 1), undefined, 3, 2);
this.zoom_out.anchor.set(0.5, 0.5);
this.layer_overlay.add(this.zoom_out);
this.tooltip.bindStaticText(this.zoom_out, "Zoom out");
2017-02-28 00:07:37 +00:00
this.character_sheet = new CharacterSheet(this, this.getWidth() - 307);
this.character_sheet.show(this.player.fleet.ships[0], false);
this.character_sheet.hide(false);
2017-03-15 21:40:19 +00:00
this.layer_overlay.add(this.character_sheet);
2015-03-25 00:00:00 +00:00
2017-06-01 22:37:43 +00:00
this.gameui.audio.startMusic("spring-thaw");
// Inputs
this.inputs.bindCheat("r", "Reveal whole map", () => this.revealAll());
2017-03-15 21:40:19 +00:00
this.setZoom(2);
// Trigger an auto-save any time we go back to the map
this.autoSave();
}
/**
* Leaving the view, unbind and destroy
*/
shutdown() {
2017-03-09 17:11:00 +00:00
this.universe = new Universe();
this.player = new Player();
super.shutdown();
}
/**
* Refresh the view
*/
refresh() {
this.setZoom(this.zoom);
}
/**
* Update info on all star systems (fog of war, available data...)
*/
2017-06-05 22:05:34 +00:00
updateInfo(current_star: Star | null, interactive = true) {
2017-03-15 23:45:52 +00:00
this.current_location.setZoom(this.zoom);
this.starlinks.forEach(linkgraphics => {
let link = <StarLink>linkgraphics.data.link;
linkgraphics.visible = this.player.hasVisitedSystem(link.first) || this.player.hasVisitedSystem(link.second);
})
2017-03-09 23:21:34 +00:00
this.starsystems.forEach(system => system.updateInfo(this.zoom, system.starsystem == current_star));
2017-06-05 22:05:34 +00:00
this.actions.setFromLocation(this.player.fleet.location, this);
if (interactive) {
this.setInteractionEnabled(true);
}
2017-01-30 00:40:33 +00:00
}
/**
* Reveal the whole map (this is a cheat)
*/
revealAll(): void {
2017-01-29 18:34:38 +00:00
this.universe.stars.forEach(star => {
star.locations.forEach(location => {
this.player.setVisited(location);
});
});
this.refresh();
2017-01-26 00:01:31 +00:00
}
/**
* Set the camera to center on a target, and to display a given span in height
*/
setCamera(x: number, y: number, span: number, duration = 500, easing = Phaser.Easing.Cubic.InOut) {
2017-01-26 00:01:31 +00:00
let scale = 1000 / span;
2017-06-05 17:53:27 +00:00
this.tweens.create(this.layer_universe.position).to({ x: 920 - x * scale, y: 540 - y * scale }, duration, easing).start();
2017-03-15 21:40:19 +00:00
this.tweens.create(this.layer_universe.scale).to({ x: scale, y: scale }, duration, easing).start();
2017-01-26 00:01:31 +00:00
}
2017-06-05 17:53:27 +00:00
/**
* Set the alpha value for all links
*/
setLinksAlpha(alpha: number) {
this.game.add.tween(this.starlinks_group).to({ alpha: alpha }, 500 * Math.abs(this.starlinks_group.alpha - alpha)).start();
}
/**
* Set the current zoom level (0, 1 or 2)
*/
2017-01-26 00:01:31 +00:00
setZoom(level: number) {
2017-03-09 17:11:00 +00:00
let current_star = this.player.fleet.location ? this.player.fleet.location.star : null;
if (!current_star || level <= 0) {
2017-01-26 00:01:31 +00:00
this.setCamera(0, 0, this.universe.radius * 2);
2017-06-05 17:53:27 +00:00
this.setLinksAlpha(1);
2017-01-26 00:01:31 +00:00
this.zoom = 0;
} else if (level == 1) {
2017-01-26 23:01:04 +00:00
// TODO Zoom to next-jump accessible
2017-01-26 00:01:31 +00:00
this.setCamera(current_star.x, current_star.y, this.universe.radius * 0.5);
2017-06-05 17:53:27 +00:00
this.setLinksAlpha(0.6);
2017-01-26 00:01:31 +00:00
this.zoom = 1;
} else {
this.setCamera(current_star.x, current_star.y, current_star.radius * 2);
2017-06-05 17:53:27 +00:00
this.setLinksAlpha(0.2);
2017-01-26 00:01:31 +00:00
this.zoom = 2;
}
2017-03-09 23:21:34 +00:00
this.updateInfo(current_star);
}
/**
* Do the jump animation to another system
2017-06-05 22:05:34 +00:00
*
* This will only work if current location is a warp
*/
2017-06-05 22:05:34 +00:00
doJump(): void {
let location = this.player.fleet.location;
if (location && location.type == StarLocationType.WARP && location.jump_dest) {
let dest_location = location.jump_dest;
let dest_star = dest_location.star;
this.player_fleet.moveToLocation(dest_location, 3, duration => {
2017-06-05 22:05:34 +00:00
this.timer.schedule(duration / 2, () => this.updateInfo(dest_star, false));
this.setCamera(dest_star.x, dest_star.y, dest_star.radius * 2, duration, Phaser.Easing.Cubic.Out);
2017-06-05 22:05:34 +00:00
}, () => {
this.setInteractionEnabled(true);
});
2017-06-05 22:05:34 +00:00
this.setInteractionEnabled(false);
}
}
2017-06-05 22:05:34 +00:00
/**
* Open the dockyard interface
*
* This will only work if current location has a dockyard
*/
openShop(): void {
let location = this.player.fleet.location;
if (location && location.shop) {
this.character_sheet.setShop(location.shop);
this.character_sheet.show(this.player.fleet.ships[0]);
}
}
/**
* Move the fleet to another location
*/
moveToLocation(dest: StarLocation): void {
if (dest != this.player.fleet.location) {
this.setInteractionEnabled(false);
this.player_fleet.moveToLocation(dest, 1, null, () => this.updateInfo(dest.star));
}
}
/**
* Set the interactive state
*/
setInteractionEnabled(enabled: boolean) {
this.actions.setVisible(enabled && this.zoom == 2, 300);
this.animations.setVisible(this.zoom_in, enabled && this.zoom < 2, 300);
this.animations.setVisible(this.zoom_out, enabled && this.zoom > 0, 300);
this.animations.setVisible(this.character_sheet, enabled, 300);
}
}
}