2017-09-24 22:23:22 +00:00
|
|
|
module TK.SpaceTac.UI {
|
2017-02-16 22:59:41 +00:00
|
|
|
/**
|
|
|
|
* Base class for all game views
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
export class BaseView extends Phaser.Scene {
|
2015-04-07 00:00:00 +00:00
|
|
|
// Link to the root UI
|
2018-01-31 18:19:50 +00:00
|
|
|
gameui!: MainUI
|
2015-04-07 00:00:00 +00:00
|
|
|
|
2015-04-15 00:00:00 +00:00
|
|
|
// Message notifications
|
2018-05-15 14:57:45 +00:00
|
|
|
messages_layer!: UIContainer
|
2018-01-31 18:19:50 +00:00
|
|
|
messages!: Messages
|
2015-04-15 00:00:00 +00:00
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
// Audio system
|
|
|
|
audio!: Audio
|
|
|
|
|
2015-04-23 22:36:57 +00:00
|
|
|
// Input and key bindings
|
2018-01-31 18:19:50 +00:00
|
|
|
inputs!: InputManager
|
2015-04-23 22:36:57 +00:00
|
|
|
|
2017-04-10 17:38:33 +00:00
|
|
|
// Animations
|
2018-01-31 18:19:50 +00:00
|
|
|
animations!: Animations
|
2018-06-03 21:27:35 +00:00
|
|
|
particles!: UIParticles
|
2017-04-10 17:38:33 +00:00
|
|
|
|
2017-02-16 22:59:41 +00:00
|
|
|
// Timing
|
2018-01-31 18:19:50 +00:00
|
|
|
timer!: Timer
|
2017-02-16 22:59:41 +00:00
|
|
|
|
2017-03-15 21:40:19 +00:00
|
|
|
// Tooltip
|
2018-05-15 14:57:45 +00:00
|
|
|
tooltip_layer!: UIContainer
|
2018-01-31 18:19:50 +00:00
|
|
|
tooltip!: Tooltip
|
2017-03-15 21:40:19 +00:00
|
|
|
|
|
|
|
// Layers
|
2018-05-15 14:57:45 +00:00
|
|
|
layers!: UIContainer
|
2017-06-08 17:32:57 +00:00
|
|
|
|
|
|
|
// Modal dialogs
|
2018-05-15 14:57:45 +00:00
|
|
|
dialogs_layer!: UIContainer
|
2017-10-09 22:59:49 +00:00
|
|
|
dialogs_opened: UIDialog[] = []
|
2017-03-15 21:40:19 +00:00
|
|
|
|
2018-03-01 23:14:09 +00:00
|
|
|
// Verbose debug output
|
2018-05-15 14:57:45 +00:00
|
|
|
debug = false
|
2018-03-01 23:14:09 +00:00
|
|
|
|
2015-04-07 00:00:00 +00:00
|
|
|
// Get the size of display
|
|
|
|
getWidth(): number {
|
2018-05-15 14:57:45 +00:00
|
|
|
return this.cameras.main.width;
|
2015-04-07 00:00:00 +00:00
|
|
|
}
|
|
|
|
getHeight(): number {
|
2018-05-15 14:57:45 +00:00
|
|
|
return this.cameras.main.height;
|
2015-04-07 00:00:00 +00:00
|
|
|
}
|
|
|
|
getMidWidth(): number {
|
|
|
|
return this.getWidth() / 2;
|
|
|
|
}
|
|
|
|
getMidHeight(): number {
|
|
|
|
return this.getHeight() / 2;
|
|
|
|
}
|
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
init(data: object) {
|
|
|
|
console.log(`Starting scene ${classname(this)}`);
|
|
|
|
|
|
|
|
this.gameui = <MainUI>this.sys.game;
|
2017-02-21 21:16:18 +00:00
|
|
|
this.timer = new Timer(this.gameui.headless);
|
2018-05-15 14:57:45 +00:00
|
|
|
this.animations = new Animations(this.tweens);
|
2018-06-03 21:27:35 +00:00
|
|
|
this.particles = new UIParticles(this);
|
2018-05-15 14:57:45 +00:00
|
|
|
this.inputs = new InputManager(this);
|
|
|
|
this.audio = new Audio(this);
|
|
|
|
this.debug = this.gameui.debug;
|
|
|
|
|
|
|
|
this.events.once("shutdown", () => this.shutdown());
|
2015-04-07 00:00:00 +00:00
|
|
|
}
|
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
shutdown() {
|
|
|
|
console.log(`Shutting down scene ${classname(this)}`);
|
2017-03-15 21:40:19 +00:00
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
this.inputs.destroy();
|
|
|
|
this.audio.stopMusic();
|
|
|
|
this.timer.cancelAll(true);
|
|
|
|
}
|
2017-02-05 22:03:35 +00:00
|
|
|
|
2018-05-15 14:57:45 +00:00
|
|
|
create() {
|
2017-05-22 20:41:34 +00:00
|
|
|
// Layers
|
2018-06-07 21:03:22 +00:00
|
|
|
this.layers = new UIContainer(this);
|
|
|
|
this.add.existing(this.layers);
|
2018-05-15 14:57:45 +00:00
|
|
|
this.layers.setName("View layers");
|
2018-06-07 21:03:22 +00:00
|
|
|
this.dialogs_layer = new UIContainer(this);
|
2018-05-15 14:57:45 +00:00
|
|
|
this.dialogs_layer.setName("Dialogs layer");
|
2018-06-07 21:03:22 +00:00
|
|
|
this.add.existing(this.dialogs_layer);
|
|
|
|
this.tooltip_layer = new UIContainer(this);
|
2018-05-15 14:57:45 +00:00
|
|
|
this.tooltip_layer.setName("Tooltip layer");
|
2018-06-07 21:03:22 +00:00
|
|
|
this.add.existing(this.tooltip_layer);
|
2017-03-15 21:40:19 +00:00
|
|
|
this.tooltip = new Tooltip(this);
|
2018-06-07 21:03:22 +00:00
|
|
|
this.messages_layer = new UIContainer(this);
|
|
|
|
this.messages_layer.setName("Messages layer");
|
|
|
|
this.add.existing(this.messages_layer);
|
2017-05-22 20:41:34 +00:00
|
|
|
this.messages = new Messages(this);
|
2017-12-06 23:25:35 +00:00
|
|
|
this.dialogs_opened = [];
|
2017-03-15 21:40:19 +00:00
|
|
|
|
2017-02-05 22:03:35 +00:00
|
|
|
// Browser console variable (for debugging purpose)
|
|
|
|
if (typeof window != "undefined") {
|
|
|
|
let session = this.gameui.session;
|
|
|
|
if (session) {
|
|
|
|
(<any>window).universe = session.universe;
|
|
|
|
(<any>window).player = session.player;
|
|
|
|
(<any>window).battle = session.player.getBattle();
|
2017-02-09 19:16:49 +00:00
|
|
|
(<any>window).view = this;
|
2017-02-05 22:03:35 +00:00
|
|
|
}
|
|
|
|
}
|
2015-04-07 00:00:00 +00:00
|
|
|
}
|
2017-03-15 21:40:19 +00:00
|
|
|
|
2017-06-08 17:32:57 +00:00
|
|
|
get options() {
|
|
|
|
return this.gameui.options;
|
|
|
|
}
|
2017-06-08 21:00:56 +00:00
|
|
|
get session() {
|
|
|
|
return this.gameui.session;
|
|
|
|
}
|
2017-06-08 17:32:57 +00:00
|
|
|
|
2017-05-31 23:11:29 +00:00
|
|
|
/**
|
|
|
|
* Go back to the router state
|
|
|
|
*/
|
|
|
|
backToRouter() {
|
2018-05-15 14:57:45 +00:00
|
|
|
this.scene.start('router');
|
2017-05-31 23:11:29 +00:00
|
|
|
}
|
|
|
|
|
2017-03-15 21:40:19 +00:00
|
|
|
/**
|
2017-10-11 20:58:08 +00:00
|
|
|
* Get or create a layer in the view, by its name
|
2017-03-15 21:40:19 +00:00
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
getLayer(name: string): UIContainer {
|
|
|
|
let layer = this.layers.getByName(name);
|
|
|
|
if (layer && layer instanceof UIContainer) {
|
|
|
|
return layer;
|
|
|
|
} else {
|
|
|
|
let layer = new UIContainer(this);
|
|
|
|
layer.setName(name);
|
|
|
|
this.layers.add(layer);
|
|
|
|
return layer;
|
2017-10-11 20:58:08 +00:00
|
|
|
}
|
2017-03-15 21:40:19 +00:00
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a network connection to the backend server
|
|
|
|
*/
|
|
|
|
getConnection(): Multi.Connection {
|
|
|
|
let device_id = this.gameui.getDeviceId();
|
|
|
|
if (device_id) {
|
|
|
|
return new Multi.Connection(device_id, new Multi.ParseRemoteStorage());
|
|
|
|
} else {
|
|
|
|
// TODO Should warn the user !
|
|
|
|
return new Multi.Connection("fake", new Multi.FakeRemoteStorage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Auto-save current session to cloud
|
|
|
|
*
|
|
|
|
* This may be called at key points during the gameplay
|
|
|
|
*/
|
|
|
|
autoSave(): void {
|
|
|
|
let session = this.gameui.session;
|
2017-06-08 21:58:23 +00:00
|
|
|
if (session.primary) {
|
|
|
|
let connection = this.getConnection();
|
|
|
|
connection.publish(session, session.getDescription())
|
|
|
|
.then(() => this.messages.addMessage("Auto-saved to cloud"))
|
|
|
|
.catch(console.error)
|
|
|
|
//.catch(() => this.messages.addMessage("Error saving game to cloud"));
|
|
|
|
}
|
2017-05-04 23:19:28 +00:00
|
|
|
}
|
2017-05-15 23:15:07 +00:00
|
|
|
|
|
|
|
/**
|
2017-06-08 17:32:57 +00:00
|
|
|
* Open options dialog
|
2017-05-15 23:15:07 +00:00
|
|
|
*/
|
2018-04-12 22:03:29 +00:00
|
|
|
showOptions(credits = false): void {
|
|
|
|
new OptionsDialog(this, credits);
|
2017-05-15 23:15:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set a value in localStorage, if available
|
|
|
|
*/
|
|
|
|
setStorage(key: string, value: string): void {
|
|
|
|
if (typeof localStorage != "undefined") {
|
|
|
|
localStorage.setItem("spacetac-" + key, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get a value from localStorage
|
|
|
|
*/
|
|
|
|
getStorage(key: string): string | null {
|
|
|
|
if (typeof localStorage != "undefined") {
|
|
|
|
return localStorage.getItem("spacetac-" + key);
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the mouse is inside a given area
|
|
|
|
*/
|
|
|
|
isMouseInside(area: IBounded): boolean {
|
2018-05-15 14:57:45 +00:00
|
|
|
let pos = this.input.activePointer.position;
|
2017-05-15 23:15:07 +00:00
|
|
|
return pos.x >= area.x && pos.x < area.x + area.width && pos.y >= area.y && pos.y < area.y + area.height;
|
|
|
|
}
|
2017-05-28 20:37:07 +00:00
|
|
|
|
|
|
|
/**
|
2017-07-26 22:54:56 +00:00
|
|
|
* Get a new image from an atlas name
|
2017-05-28 20:37:07 +00:00
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
newImage(name: string, x = 0, y = 0): UIImage {
|
2017-07-26 22:54:56 +00:00
|
|
|
let info = this.getImageInfo(name);
|
2018-05-15 14:57:45 +00:00
|
|
|
let result = this.add.image(x, y, info.key, info.frame);
|
2017-07-26 22:54:56 +00:00
|
|
|
result.name = name;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2017-08-21 23:21:34 +00:00
|
|
|
/**
|
|
|
|
* Update an image from an atlas name
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
changeImage(image: UIImage, name: string): void {
|
2017-08-21 23:21:34 +00:00
|
|
|
let info = this.getImageInfo(name);
|
2018-05-15 14:57:45 +00:00
|
|
|
image.setName(name);
|
|
|
|
image.setTexture(info.key, info.frame);
|
2017-08-21 23:21:34 +00:00
|
|
|
}
|
|
|
|
|
2017-07-26 22:54:56 +00:00
|
|
|
/**
|
|
|
|
* Get an image from atlases
|
|
|
|
*/
|
2018-05-15 14:57:45 +00:00
|
|
|
getImageInfo(name: string): { key: string, frame: number | string, exists: boolean } {
|
|
|
|
if (this.textures.exists(name)) {
|
2018-02-08 15:16:03 +00:00
|
|
|
return { key: name, frame: 0, exists: true };
|
2017-10-25 22:45:53 +00:00
|
|
|
} else {
|
2018-03-08 19:16:05 +00:00
|
|
|
for (let j = 1; j <= 3; j++) {
|
|
|
|
let i = 1;
|
2018-05-15 14:57:45 +00:00
|
|
|
while (this.textures.exists(`atlas${j}-${i}`)) {
|
|
|
|
let frames = this.textures.get(`atlas${j}-${i}`).getFrameNames();
|
|
|
|
let frame = first(frames, frame => AssetLoading.getKey(frame) == `data-stage${j}-image-${name}`);
|
2018-03-08 19:16:05 +00:00
|
|
|
if (frame) {
|
2018-05-15 14:57:45 +00:00
|
|
|
return { key: `atlas${j}-${i}`, frame: frame, exists: true };
|
2018-03-08 19:16:05 +00:00
|
|
|
}
|
|
|
|
i++;
|
2017-10-25 22:45:53 +00:00
|
|
|
}
|
2017-07-26 22:54:56 +00:00
|
|
|
}
|
2018-02-08 15:16:03 +00:00
|
|
|
return { key: `-missing-${name}`, frame: 0, exists: false };
|
2017-07-26 22:54:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2017-10-10 22:32:46 +00:00
|
|
|
* Returns the first image found in atlases
|
2017-07-26 22:54:56 +00:00
|
|
|
*/
|
2017-10-10 22:32:46 +00:00
|
|
|
getFirstImage(...names: string[]): string {
|
|
|
|
return first(names, name => this.getImageInfo(name).key.substr(0, 9) != '-missing-') || names[names.length - 1];
|
2017-05-28 20:37:07 +00:00
|
|
|
}
|
2018-05-15 14:57:45 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if the scene is paused
|
|
|
|
*/
|
|
|
|
isPaused(): boolean {
|
|
|
|
return this.time.paused;
|
|
|
|
}
|
2015-04-07 00:00:00 +00:00
|
|
|
}
|
|
|
|
}
|