diff --git a/src/core/equipments/IronHull.ts b/src/core/equipments/IronHull.ts index 75e3aee..088f2ba 100644 --- a/src/core/equipments/IronHull.ts +++ b/src/core/equipments/IronHull.ts @@ -3,7 +3,7 @@ module TS.SpaceTac.Equipments { export class IronHull extends LootTemplate { constructor() { - super(SlotType.Hull, "IronHull"); + super(SlotType.Hull, "Iron Hull"); this.min_level = new IntegerRange(1, 3); diff --git a/src/ui/BaseView.ts b/src/ui/BaseView.ts index 98ac3e4..5b2955c 100644 --- a/src/ui/BaseView.ts +++ b/src/ui/BaseView.ts @@ -15,6 +15,12 @@ module TS.SpaceTac.UI { // Timing timer: Timer; + // Tooltip + tooltip: Tooltip; + + // Layers + layers: Phaser.Group; + // Get the size of display getWidth(): number { return this.game.width || 1280; @@ -35,12 +41,20 @@ module TS.SpaceTac.UI { } create() { + this.game.stage.backgroundColor = 0x000000; + + // View layers + this.layers = this.add.group(); + // Notifications this.messages = new Messages(this); // Input manager this.inputs = new InputManager(this); + // Tooltip + this.tooltip = new Tooltip(this); + // Browser console variable (for debugging purpose) if (typeof window != "undefined") { let session = this.gameui.session; @@ -60,5 +74,13 @@ module TS.SpaceTac.UI { this.timer.cancelAll(true); } + + /** + * Add a new layer in the view + */ + addLayer(): Phaser.Group { + let layer = this.add.group(this.layers); + return layer; + } } } diff --git a/src/ui/MainMenu.spec.ts b/src/ui/MainMenu.spec.ts index eb7445a..11df96d 100644 --- a/src/ui/MainMenu.spec.ts +++ b/src/ui/MainMenu.spec.ts @@ -8,16 +8,12 @@ module TS.SpaceTac.UI.Specs { it("adds moving stars, a title and three buttons", function () { let view = testgame.ui.state.getCurrentState(); - expect(view.world.children.length).toBe(301); - - let group = view.world.children[300]; - expect(group instanceof Phaser.Group).toBe(true); - - expect(group.children.length).toBe(4); - expect(group.children[0] instanceof Phaser.Button).toBe(true); - expect(group.children[1] instanceof Phaser.Button).toBe(true); - expect(group.children[2] instanceof Phaser.Button).toBe(true); - expect(group.children[3] instanceof Phaser.Image).toBe(true); + expect(view.layer_stars.children.length).toBe(300); + expect(view.layer_title.children.length).toBe(4); + expect(view.layer_title.children[0] instanceof Phaser.Button).toBe(true); + expect(view.layer_title.children[1] instanceof Phaser.Button).toBe(true); + expect(view.layer_title.children[2] instanceof Phaser.Button).toBe(true); + expect(view.layer_title.children[3] instanceof Phaser.Image).toBe(true); }); }); } diff --git a/src/ui/MainMenu.ts b/src/ui/MainMenu.ts index 9506221..74135b6 100644 --- a/src/ui/MainMenu.ts +++ b/src/ui/MainMenu.ts @@ -2,42 +2,44 @@ module TS.SpaceTac.UI { export class MainMenu extends BaseView { - group: Phaser.Group; + layer_stars: Phaser.Group; + layer_title: Phaser.Group; button_new_game: Phaser.Button; button_quick_battle: Phaser.Button; button_load_game: Phaser.Button; create() { - this.game.stage.backgroundColor = "#000000"; + super.create(); + + this.layer_stars = this.addLayer(); + this.layer_title = this.addLayer(); + this.layer_title.x = 5000; // Stars for (let i = 0; i < 300; i++) { let fade = Math.random() * 0.5 + 0.5; let x = Math.random() * 0.998 + 0.001; - let star = this.add.image(1920 * x, Math.random() * 1080, "menu-star"); + let star = this.add.image(1920 * x, Math.random() * 1080, "menu-star", 0, this.layer_stars); star.anchor.set(0.5, 0.5); star.alpha = 0.7 * fade; star.scale.set(0.1 * fade, 0.1 * fade); this.tweens.create(star).to({ x: -30 }, 30000 * x / fade).to({ x: 1950 }, 0.00001).to({ x: 1920 * x }, 30000 * (1 - x) / fade).loop().start(); } - this.group = this.add.group(); - this.group.x = 5000; - // Menu buttons - this.button_new_game = this.addButton(322, 674, "New Game", this.onNewGame); - this.button_load_game = this.addButton(960, 674, "Load Game", this.onLoadGame); - this.button_quick_battle = this.addButton(1606, 674, "Quick Battle", this.onQuickBattle); + this.button_new_game = this.addButton(322, 674, "New Game", "Start a new campaign in a generated universe", this.onNewGame); + this.button_load_game = this.addButton(960, 674, "Load Game", "Load a saved campaign", this.onLoadGame); + this.button_quick_battle = this.addButton(1606, 674, "Quick Battle", "Play a single generated battle", this.onQuickBattle); // Title - let title = this.add.image(960, 225, "menu-title", 0, this.group); + let title = this.add.image(960, 225, "menu-title", 0, this.layer_title); title.anchor.set(0.5, 0); - this.tweens.create(this.group).to({ x: 0 }, 3000, Phaser.Easing.Circular.Out).start(); + this.tweens.create(this.layer_title).to({ x: 0 }, 3000, Phaser.Easing.Circular.Out).start(); } - addButton(x: number, y: number, caption: string, callback: Function): Phaser.Button { - var button = this.add.button(x - 20, y + 20, "menu-button", callback, this, null, null, null, null, this.group); + addButton(x: number, y: number, caption: string, tooltip: string, callback: Function): Phaser.Button { + var button = this.add.button(x - 20, y + 20, "menu-button", callback, this, null, null, null, null, this.layer_title); button.anchor.set(0.5, 0); button.input.useHandCursor = true; @@ -55,6 +57,8 @@ module TS.SpaceTac.UI { text.fill = "#529aee"; }); + this.tooltip.bindStaticText(button, tooltip); + return button; } diff --git a/src/ui/battle/ActionBar.ts b/src/ui/battle/ActionBar.ts index a066f2d..b56a5f2 100644 --- a/src/ui/battle/ActionBar.ts +++ b/src/ui/battle/ActionBar.ts @@ -33,7 +33,7 @@ module TS.SpaceTac.UI { this.action_icons = []; this.ship = null; - battleview.ui.add(this); + battleview.layer_borders.add(this); // Background this.addChild(new Phaser.Image(this.game, 0, 0, "battle-actionbar", 0)); diff --git a/src/ui/battle/Arena.ts b/src/ui/battle/Arena.ts index 33009a2..d98ce94 100644 --- a/src/ui/battle/Arena.ts +++ b/src/ui/battle/Arena.ts @@ -136,6 +136,7 @@ module TS.SpaceTac.UI { if (ship) { var arena_ship = this.findShipSprite(ship); if (arena_ship) { + this.bringToTop(arena_ship); arena_ship.setPlaying(true); } this.playing = arena_ship; diff --git a/src/ui/battle/BattleView.ts b/src/ui/battle/BattleView.ts index e3579ba..1d8b6b3 100644 --- a/src/ui/battle/BattleView.ts +++ b/src/ui/battle/BattleView.ts @@ -10,8 +10,13 @@ module TS.SpaceTac.UI { // Interacting player player: Player; - // UI container - ui: Phaser.Group; + // Layers + layer_background: Phaser.Group; + layer_arena: Phaser.Group; + layer_borders: Phaser.Group; + layer_overlay: Phaser.Group; + layer_dialogs: Phaser.Group; + layer_sheets: Phaser.Group; // Battleground container arena: Arena; @@ -67,28 +72,31 @@ module TS.SpaceTac.UI { var game = this.game; + // Add layers + this.layer_background = this.addLayer(); + this.layer_arena = this.addLayer(); + this.layer_borders = this.addLayer(); + this.layer_overlay = this.addLayer(); + this.layer_dialogs = this.addLayer(); + this.layer_sheets = this.addLayer(); + // Background - game.stage.backgroundColor = 0x000000; this.background = new Phaser.Image(game, 0, 0, "battle-background", 0); - game.add.existing(this.background); + this.layer_background.add(this.background); // Add arena (local map) this.arena = new Arena(this); - game.add.existing(this.arena); - - // Add UI layer - this.ui = new Phaser.Group(game); - game.add.existing(this.ui); + this.layer_arena.add(this.arena); // Add UI elements this.action_bar = new ActionBar(this); this.ship_list = new ShipList(this); this.ship_tooltip = new ShipTooltip(this); - this.add.existing(this.ship_tooltip); + this.layer_overlay.add(this.ship_tooltip); this.outcome_layer = new Phaser.Group(this.game); - this.add.existing(this.outcome_layer); + this.layer_dialogs.add(this.outcome_layer); this.character_sheet = new CharacterSheet(this, -this.getWidth()); - this.add.existing(this.character_sheet); + this.layer_sheets.add(this.character_sheet); // "Battle" animation this.displayFightMessage(); @@ -129,8 +137,6 @@ module TS.SpaceTac.UI { this.exitTargettingMode(); this.log_processor.destroy(); - this.ui.destroy(); - this.arena.destroy(); super.shutdown(); } diff --git a/src/ui/battle/OutcomeDialog.ts b/src/ui/battle/OutcomeDialog.ts index ca104e6..216f4e0 100644 --- a/src/ui/battle/OutcomeDialog.ts +++ b/src/ui/battle/OutcomeDialog.ts @@ -13,26 +13,36 @@ module TS.SpaceTac.UI { this.addChild(title); if (victory) { - this.addChild(new Phaser.Button(this.game, 344, 842, "battle-outcome-button-loot", () => { + let button = new Phaser.Button(this.game, 344, 842, "battle-outcome-button-loot", () => { // Open loot screen if (outcome.winner) { parent.character_sheet.show(outcome.winner.ships[0]); parent.character_sheet.setLoot(outcome.loot); } - })); - this.addChild(new Phaser.Button(this.game, 766, 842, "battle-outcome-button-map", () => { + }) + parent.tooltip.bindStaticText(button, "Open character sheet to loot equipment from defeated fleet"); + this.addChild(button); + + button = new Phaser.Button(this.game, 766, 842, "battle-outcome-button-map", () => { // Exit battle and go back to map parent.exitBattle(); - })); + }); + parent.tooltip.bindStaticText(button, "Exit the battle and go back to the map"); + this.addChild(button); } else { - this.addChild(new Phaser.Button(this.game, 344, 842, "battle-outcome-button-revert", () => { + let button = new Phaser.Button(this.game, 344, 842, "battle-outcome-button-revert", () => { // Revert just before battle parent.revertBattle(); - })); - this.addChild(new Phaser.Button(this.game, 766, 842, "battle-outcome-button-menu", () => { + }); + parent.tooltip.bindStaticText(button, "Go back to where the fleet was before the battle happened"); + this.addChild(button); + + button = new Phaser.Button(this.game, 766, 842, "battle-outcome-button-menu", () => { // Quit the game, and go back to menu parent.gameui.quitGame(); - })); + }); + parent.tooltip.bindStaticText(button, "Quit the game, and go back to main menu"); + this.addChild(button); } } } diff --git a/src/ui/battle/ShipList.ts b/src/ui/battle/ShipList.ts index 0839fc7..3147f32 100644 --- a/src/ui/battle/ShipList.ts +++ b/src/ui/battle/ShipList.ts @@ -22,7 +22,7 @@ module TS.SpaceTac.UI { this.playing = null; this.hovered = null; - battleview.ui.add(this); + battleview.layer_borders.add(this); if (battleview.battle) { this.setShipsFromBattle(battleview.battle); diff --git a/src/ui/character/CharacterEquipment.ts b/src/ui/character/CharacterEquipment.ts index 8c0e26f..afac84f 100644 --- a/src/ui/character/CharacterEquipment.ts +++ b/src/ui/character/CharacterEquipment.ts @@ -9,7 +9,7 @@ module TS.SpaceTac.UI { /** * Display a ship equipment, either attached to a slot, in cargo, or being dragged down */ - export class CharacterEquipment extends Phaser.Image { + export class CharacterEquipment extends Phaser.Button { equipment: Equipment; constructor(sheet: CharacterSheet, equipment: Equipment) { @@ -22,6 +22,9 @@ module TS.SpaceTac.UI { this.scale.set(0.5, 0.5); this.setupDragDrop(sheet); + + // TODO better tooltip + sheet.view.tooltip.bindStaticText(this, equipment.name); } /** diff --git a/src/ui/character/CharacterSheet.ts b/src/ui/character/CharacterSheet.ts index 0d9449b..7d28193 100644 --- a/src/ui/character/CharacterSheet.ts +++ b/src/ui/character/CharacterSheet.ts @@ -8,6 +8,9 @@ module TS.SpaceTac.UI { * Character sheet, displaying ship characteristics */ export class CharacterSheet extends Phaser.Image { + // Parent view + view: BaseView; + // X positions xshown: number; xhidden: number; @@ -52,6 +55,8 @@ module TS.SpaceTac.UI { constructor(view: BaseView, xhidden = -2000, xshown = 0) { super(view.game, 0, 0, "character-sheet"); + this.view = view; + this.x = xhidden; this.xshown = xshown; this.xhidden = xhidden; @@ -60,6 +65,7 @@ module TS.SpaceTac.UI { let close_button = new Phaser.Button(this.game, view.getWidth(), 0, "character-close", () => this.hide()); close_button.anchor.set(1, 0); this.addChild(close_button); + view.tooltip.bindStaticText(close_button, "Close the character sheet"); this.ship_name = new Phaser.Text(this.game, 758, 48, "", { align: "center", font: "30pt Arial", fill: "#FFFFFF" }); this.ship_name.anchor.set(0.5, 0.5); @@ -147,6 +153,8 @@ module TS.SpaceTac.UI { let portrait_pic = new Phaser.Image(this.game, 0, 0, `ship-${ship.model}-portrait`); portrait_pic.anchor.set(0.5, 0.5); new_portrait.addChild(portrait_pic); + + this.view.tooltip.bindDynamicText(new_portrait, () => ship.name); } }); diff --git a/src/ui/character/CharacterSlot.ts b/src/ui/character/CharacterSlot.ts index 42f4c8c..39e3ca6 100644 --- a/src/ui/character/CharacterSlot.ts +++ b/src/ui/character/CharacterSlot.ts @@ -10,9 +10,10 @@ module TS.SpaceTac.UI { this.sheet = sheet; - let sloticon = new Phaser.Image(this.game, 150, 150, `character-slot-${SlotType[slot].toLowerCase()}`); + let sloticon = new Phaser.Button(this.game, 150, 150, `character-slot-${SlotType[slot].toLowerCase()}`); sloticon.anchor.set(0.5, 0.5); this.addChild(sloticon); + sheet.view.tooltip.bindStaticText(sloticon, `${SlotType[slot]} slot`); } /** diff --git a/src/ui/common/Tools.spec.ts b/src/ui/common/Tools.spec.ts index 06bb461..df9f917 100644 --- a/src/ui/common/Tools.spec.ts +++ b/src/ui/common/Tools.spec.ts @@ -2,6 +2,18 @@ module TS.SpaceTac.UI.Specs { describe("Tools", function () { let testgame = setupEmptyView(); + it("keeps objects inside bounds", function () { + let image = testgame.baseview.add.graphics(150, 100); + image.beginFill(0xff0000); + image.drawEllipse(50, 25, 50, 25); + image.endFill(); + + Tools.keepInside(image, { x: 0, y: 0, width: 200, height: 200 }); + + expect(image.x).toBe(100); + expect(image.y).toBe(100); + }); + it("normalizes angles", function () { expect(Tools.normalizeAngle(0)).toEqual(0); expect(Tools.normalizeAngle(0.1)).toBeCloseTo(0.1, 0.000001); diff --git a/src/ui/common/Tools.ts b/src/ui/common/Tools.ts index bab659a..0d5400c 100644 --- a/src/ui/common/Tools.ts +++ b/src/ui/common/Tools.ts @@ -1,6 +1,26 @@ module TS.SpaceTac.UI { // Common UI tools functions export class Tools { + /** + * Reposition an object to remain inside a container + */ + static keepInside(obj: Phaser.Button | Phaser.Sprite | Phaser.Image | Phaser.Group | Phaser.Graphics, rect: { x: number, y: number, width: number, height: number }) { + let objbounds = obj.getBounds(); + + if (obj.y + objbounds.height > rect.height) { + obj.y = rect.height - objbounds.height; + } + if (obj.y < 0) { + obj.y = 0; + } + + if (obj.x + objbounds.width > rect.width) { + obj.x = rect.width - objbounds.width; + } + if (obj.x < 0) { + obj.x = 0; + } + } /** * Setup a hover/hold/click routine on an object @@ -39,6 +59,12 @@ module TS.SpaceTac.UI { } } + if (obj.events) { + obj.events.onDestroy.addOnce(() => { + prevententer(); + }); + } + obj.onInputOver.add(() => { cursorinside = true; enternext = Timer.global.schedule(hovertime, effectiveenter); diff --git a/src/ui/common/Tooltip.ts b/src/ui/common/Tooltip.ts new file mode 100644 index 0000000..65d5ebf --- /dev/null +++ b/src/ui/common/Tooltip.ts @@ -0,0 +1,73 @@ +module TS.SpaceTac.UI { + /** + * Tooltip system, to display information on hover + */ + export class Tooltip { + private view: BaseView; + private container: Phaser.Group; + + constructor(view: BaseView) { + this.view = view; + this.container = new Phaser.Group(view.game); + } + + /** + * Bind to an UI component + * + * When the component is hovered, the function is called to allow filling the tooltip container + */ + bind(obj: Phaser.Button, func: (container: Phaser.Group) => boolean): void { + Tools.setHoverClick(obj, + // enter + () => { + this.container.visible = false; + if (func(this.container)) { + // position + let bounds = obj.getBounds(); + this.container.position.set(bounds.x + bounds.width + 4, bounds.y + bounds.height + 4); + + // add background + let ttbounds = this.container.getBounds(); + let background = new Phaser.Graphics(this.container.game, 0, 0); + this.container.add(background); + background.beginFill(0x202225, 0.8); + background.drawRect(-10, -10, ttbounds.width + 20, ttbounds.height + 20); + background.endFill(); + this.container.sendToBack(background); + + // display + Tools.keepInside(this.container, { x: 0, y: 0, width: this.view.getWidth(), height: this.view.getHeight() }); + this.container.visible = true; + } + }, + // leave + () => { + this.container.removeAll(true); + this.container.visible = false; + }, + // click + () => { + this.container.removeAll(true); + this.container.visible = false; + } + ); + } + + /** + * Bind to an UI component to display a dynamic text + */ + bindDynamicText(obj: Phaser.Button, text_getter: () => string): void { + this.bind(obj, container => { + container.add(new Phaser.Text(container.game, 0, 0, text_getter(), { font: "bold 20pt Arial", fill: "#cccccc" })); + return true; + }); + } + + /** + * Bind to an UI component to display a simple text + */ + bindStaticText(obj: Phaser.Button, text: string): void { + this.bindDynamicText(obj, () => text); + } + } +} \ No newline at end of file diff --git a/src/ui/map/StarSystemDisplay.ts b/src/ui/map/StarSystemDisplay.ts index 6798ffb..94038f5 100644 --- a/src/ui/map/StarSystemDisplay.ts +++ b/src/ui/map/StarSystemDisplay.ts @@ -1,6 +1,8 @@ module TS.SpaceTac.UI { // Group to display a star system export class StarSystemDisplay extends Phaser.Image { + view: UniverseMapView; + circles: Phaser.Group; starsystem: Star; player: Player; fleet_display: FleetDisplay; @@ -9,6 +11,8 @@ module TS.SpaceTac.UI { constructor(parent: UniverseMapView, starsystem: Star) { super(parent.game, starsystem.x, starsystem.y, "map-starsystem-background"); + this.view = parent; + this.anchor.set(0.5, 0.5); let scale = this.width; @@ -19,6 +23,8 @@ module TS.SpaceTac.UI { this.fleet_display = parent.player_fleet; // Show boundary + this.circles = new Phaser.Group(this.game); + this.addChild(this.circles); this.addCircle(starsystem.radius); // Show locations @@ -36,6 +42,17 @@ module TS.SpaceTac.UI { location_sprite = this.addImage(location.x, location.y, "map-location-warp", fleet_move); } + this.view.tooltip.bindDynamicText(location_sprite, () => { + if (location == this.player.fleet.location) { + return "Current fleet location"; + } else { + let visited = this.player.hasVisitedLocation(location); + let loctype = StarLocationType[location.type].toLowerCase(); + let danger = (visited && location.encounter) ? " [enemy fleet detected !]" : ""; + return `${visited ? "Visited" : "Unvisited"} ${loctype} - Move the fleet there${danger}`; + } + }); + if (location_sprite) { let key = this.getVisitedKey(location); let status_badge = this.addImage(location.x + 0.005, location.y + 0.005, key); @@ -57,7 +74,7 @@ module TS.SpaceTac.UI { let circle = this.game.add.graphics(0, 0); circle.lineStyle(width, color); circle.drawCircle(0, 0, radius * 2 / this.scale.x); - this.addChild(circle); + this.circles.add(circle); return circle; } diff --git a/src/ui/map/UniverseMapView.ts b/src/ui/map/UniverseMapView.ts index f5687a3..907976f 100644 --- a/src/ui/map/UniverseMapView.ts +++ b/src/ui/map/UniverseMapView.ts @@ -11,8 +11,11 @@ module TS.SpaceTac.UI { // Interacting player player = new Player(); + // Layers + layer_universe: Phaser.Group; + layer_overlay: Phaser.Group; + // Star systems - group: Phaser.Group; starsystems: StarSystemDisplay[] = []; starlinks: Phaser.Graphics[] = []; @@ -44,8 +47,8 @@ module TS.SpaceTac.UI { create() { super.create(); - this.group = new Phaser.Group(this.game); - this.add.existing(this.group); + this.layer_universe = this.addLayer(); + this.layer_overlay = this.addLayer(); this.starlinks = this.universe.starlinks.map(starlink => { let loc1 = starlink.first.getWarpLocationTo(starlink.second); @@ -59,33 +62,41 @@ module TS.SpaceTac.UI { } return result; }); - this.starlinks.forEach(starlink => this.group.addChild(starlink)); + this.starlinks.forEach(starlink => this.layer_universe.add(starlink)); this.player_fleet = new FleetDisplay(this, this.player.fleet); this.starsystems = this.universe.stars.map(star => new StarSystemDisplay(this, star)); - this.starsystems.forEach(starsystem => this.group.addChild(starsystem)); + this.starsystems.forEach(starsystem => this.layer_universe.add(starsystem)); - this.group.addChild(this.player_fleet); + this.layer_universe.add(this.player_fleet); this.button_jump = new Phaser.Button(this.game, 0, 0, "map-button-jump", () => this.doJump()); this.button_jump.anchor.set(0.5, 0.5); this.button_jump.visible = false; - this.group.addChild(this.button_jump); + this.layer_universe.add(this.button_jump); + this.tooltip.bindStaticText(this.button_jump, "Engage warp drive to jump to another star system"); - this.setZoom(2); - this.add.button(1520, 100, "map-zoom-in", () => this.setZoom(this.zoom + 1)).anchor.set(0.5, 0.5); - this.add.button(1520, 980, "map-zoom-out", () => this.setZoom(this.zoom - 1)).anchor.set(0.5, 0.5); + let button = new Phaser.Button(this.game, 1520, 100, "map-zoom-in", () => this.setZoom(this.zoom + 1)); + button.anchor.set(0.5, 0.5); + this.layer_overlay.add(button); + this.tooltip.bindStaticText(button, "Zoom in"); + button = new Phaser.Button(this.game, 1520, 980, "map-zoom-out", () => this.setZoom(this.zoom - 1)); + button.anchor.set(0.5, 0.5); + this.layer_overlay.add(button); + this.tooltip.bindStaticText(button, "Zoom out"); this.character_sheet = new CharacterSheet(this, this.getWidth() - 307); this.character_sheet.show(this.player.fleet.ships[0], false); this.character_sheet.hide(false); - this.add.existing(this.character_sheet); + this.layer_overlay.add(this.character_sheet); this.gameui.audio.startMusic("walking-along"); // Inputs this.inputs.bindCheat(Phaser.Keyboard.R, "Reveal whole map", this.revealAll); + + this.setZoom(2); } /** @@ -132,8 +143,8 @@ module TS.SpaceTac.UI { */ setCamera(x: number, y: number, span: number, duration = 500, easing = Phaser.Easing.Cubic.InOut) { let scale = 1000 / span; - this.tweens.create(this.group.position).to({ x: 800 - x * scale, y: 540 - y * scale }, duration, easing).start(); - this.tweens.create(this.group.scale).to({ x: scale, y: scale }, duration, easing).start(); + this.tweens.create(this.layer_universe.position).to({ x: 800 - x * scale, y: 540 - y * scale }, duration, easing).start(); + this.tweens.create(this.layer_universe.scale).to({ x: scale, y: scale }, duration, easing).start(); } /**