1
0
Fork 0

Improved buttons for battle result dialog

This commit is contained in:
Michaël Lemaire 2017-08-22 00:01:11 +02:00
parent a2f783d5fc
commit b8a792a300
24 changed files with 107 additions and 68 deletions

View file

@ -22,7 +22,7 @@ If you want to build on your computer, clone the repository, then run:
./spacetac install # Install dependencies
./spacetac run build # Build the final JS
./spacetac run pack # Pack the images and sounds
./spacetac run atlas # Pack the images and sounds
./spacetac test # Run unit tests
./spacetac start # Start development server, and open game in web browser

10
TODO.md
View file

@ -19,7 +19,7 @@ Map/story
* Allow to cancel secondary missions
* Forbid to end up with more than 5 ships in the fleet because of escorts
* Fix problems when several dialogs are active at the same time
* Handle case where cargo is full to give a reward (give money ?)
* Handle case where cargo is full to give a reward (give money?)
Character sheet
---------------
@ -39,13 +39,13 @@ Battle
* Add quick animation of playing ship indicator, on ship change
* Display a hint when a move-fire simulation failed (cannot enter exclusion area for example)
* Display effects description instead of attribute changes
* Display radius and power usage hints for area effects on action icon hover + add confirmation ?
* Display radius and power usage hints for area effects on action icon hover + add confirmation?
* Any displayed info should be based on a ship copy stored in ArenaShip, and in sync with current log index (not the game state ship)
* Add engine trail effect, and sound
* Fix targetting not resetting on current cursor location when using keyboard shortcuts
* Allow to skip animations, and allow no animation mode
* Find incentives to move from starting position (permanent drones or anomalies ?)
* Add a "loot all" button, disable the loot button if there is no loot
* Find incentives to move from starting position (permanent drones or anomalies?)
* Add a "loot all" button (on the character sheet or outcome dialog?)
* Do not focus on ship while targetting for area effects (dissociate hover and target)
* Repair drone has its activation effect sometimes displayed as permanent effect on ships in the radius
* Merge identical sticky effects
@ -110,7 +110,7 @@ Postponed
* Replays
* Multiplayer/co-op
* Formation or deployment phase
* Add ship personality (with icons to identify ?), with reaction dialogs
* Add ship personality (with icons to identify?), with reaction dialogs
* New battle internal flow: any game state change should be done through revertable events
* Animated arena background, instead of big picture
* Hide enemy information (shield, hull, weapons), until they are in play, or until a "spy" effect is used

View file

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View file

Before

Width:  |  Height:  |  Size: 84 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

View file

@ -7,7 +7,7 @@
"shell": "${SHELL} || true",
"postinstall": "rm -rf out/vendor && mkdir -p out/vendor && cp -r node_modules/phaser/build out/vendor/phaser && cp -r node_modules/phaser-plugin-scene-graph/dist out/vendor/phaser-plugin-scene-graph && cp -r node_modules/parse/dist out/vendor/parse && cp -r node_modules/jasmine-core/lib/jasmine-core out/vendor/jasmine",
"build": "tsc -p .",
"pack": "rm -f out/assets/atlas* && find graphics/exported -name '*.png' -print0 | xargs -0 gf-pack --name out/assets/atlas --fullpath --width 1024 --height 1024 --square --powerOfTwo --trim --padding 2",
"atlas": "rm -f out/assets/atlas* && find graphics/exported -name '*.png' -print0 | xargs -0 gf-pack --name out/assets/atlas --fullpath --width 1024 --height 1024 --square --powerOfTwo --trim --padding 2",
"pretest": "tsc -p .",
"test": "karma start spec/support/karma.conf.js && remap-istanbul -i out/coverage/coverage.json -o out/coverage -t html",
"prestart": "tsc -p . || true",
@ -41,4 +41,4 @@
"phaser": "^2.6.2",
"phaser-plugin-scene-graph": "^1.0.4"
}
}
}

View file

@ -19,6 +19,7 @@ module TS.SpaceTac.UI {
this.loadImage("common/button-ok.png");
this.loadImage("common/button-cancel.png");
this.loadImage("common/dialog.png");
this.loadSheet("common/dialog-textbutton.png", 316, 59);
this.loadSheet("common/dialog-close.png", 92, 82);
this.loadImage("menu/title.png");
this.loadImage("menu/button.png");
@ -51,13 +52,6 @@ module TS.SpaceTac.UI {
this.loadImage("battle/weapon/hot.png");
this.loadImage("battle/weapon/shield-impact.png");
this.loadImage("battle/weapon/blast.png");
this.loadImage("battle/outcome/dialog.png");
this.loadImage("battle/outcome/title-victory.png");
this.loadImage("battle/outcome/title-defeat.png");
this.loadImage("battle/outcome/button-menu.png");
this.loadImage("battle/outcome/button-map.png");
this.loadImage("battle/outcome/button-revert.png");
this.loadImage("battle/outcome/button-loot.png");
this.loadImage("map/starsystem-background.png");
this.loadImage("map/current-location.png");
this.loadImage("map/name.png");

View file

@ -41,9 +41,6 @@ module TS.SpaceTac.UI {
// Ship tooltip
ship_tooltip: ShipTooltip
// Outcome dialog layer
outcome_layer: Phaser.Group
// Character sheet
character_sheet: CharacterSheet
@ -101,8 +98,6 @@ module TS.SpaceTac.UI {
this.action_bar = new ActionBar(this);
this.ship_list = new ShipList(this);
this.ship_tooltip = new ShipTooltip(this);
this.outcome_layer = new Phaser.Group(this.game);
this.layer_dialogs.add(this.outcome_layer);
this.character_sheet = new CharacterSheet(this, -this.getWidth());
this.layer_sheets.add(this.character_sheet);
@ -250,8 +245,7 @@ module TS.SpaceTac.UI {
this.battle.stats.processLog(this.battle.log, this.player.fleet);
let dialog = new OutcomeDialog(this, this.player, this.battle.outcome, this.battle.stats);
dialog.moveToLayer(this.outcome_layer);
new OutcomeDialog(this, this.player, this.battle.outcome, this.battle.stats);
} else {
console.error("Battle not ended !");
}

View file

@ -1,45 +1,87 @@
/// <reference path="../common/UIComponent.ts" />
/// <reference path="../common/UIDialog.ts" />
module TS.SpaceTac.UI {
/**
* Dialog to display battle outcome
*/
export class OutcomeDialog extends UIComponent {
export class OutcomeDialog extends UIDialog {
battleview: BattleView
player: Player
outcome: BattleOutcome
stats: BattleStats
constructor(parent: BattleView, player: Player, outcome: BattleOutcome, stats: BattleStats) {
super(parent, 1428, 1032, "battle-outcome-dialog");
super(parent);
let victory = outcome.winner && (outcome.winner.player == player);
this.addImage(714, 164, victory ? "battle-outcome-title-victory" : "battle-outcome-title-defeat");
this.battleview = parent;
this.player = player;
this.outcome = outcome;
this.stats = stats;
if (victory) {
this.addButton(502, 871, () => {
parent.character_sheet.show(nn(outcome.winner).ships[0]);
parent.character_sheet.setLoot(outcome.loot);
}, "battle-outcome-button-loot", 0, 0, "Open character sheet to loot equipment from defeated fleet");
this.refreshContent();
}
this.addButton(924, 871, () => {
parent.exitBattle();
}, "battle-outcome-button-map", 0, 0, "Exit the battle and go back to the map");
} else {
this.addButton(502, 871, () => {
parent.revertBattle();
}, "battle-outcome-button-revert", 0, 0, "Go back to where the fleet was before the battle happened");
/**
* Shortcut to add a single action button at the bottom of dialog
*/
addActionButton(x: number, text: string, tooltip: string, action: Function) {
let button = this.addButton(x, 885, action, "common-dialog-textbutton", 0, 1, tooltip);
button.addChild(this.addText(0, 0, text, "#d9e0e5"));
}
this.addButton(924, 871, () => {
// Quit the game, and go back to menu
parent.gameui.quitGame();
}, "battle-outcome-button-menu", 0, 0, "Quit the game, and go back to main menu");
}
/**
* Refresh the whole dialog
*/
refreshContent(): void {
let parent = this.battleview;
let outcome = this.outcome;
let victory = outcome.winner && (outcome.winner.player == this.player);
this.addText(780, 270, "You", "#ffffff", 20);
this.addText(980, 270, "Enemy", "#ffffff", 20);
stats.getImportant(10).forEach((stat, index) => {
this.addText(500, 314 + 40 * index, stat.name, "#ffffff", 20);
this.addText(780, 314 + 40 * index, stat.attacker.toString(), "#8ba883", 20, true);
this.addText(980, 314 + 40 * index, stat.defender.toString(), "#cd6767", 20, true);
this.clearContent();
this.addImage(747, 180, victory ? "battle-outcome-title-victory" : "battle-outcome-title-defeat");
this.addText(815, 320, "You", "#ffffff", 20);
this.addText(1015, 320, "Enemy", "#ffffff", 20);
this.stats.getImportant(10).forEach((stat, index) => {
this.addText(530, 364 + 40 * index, stat.name, "#ffffff", 20);
this.addText(815, 364 + 40 * index, stat.attacker.toString(), "#8ba883", 20, true);
this.addText(1015, 364 + 40 * index, stat.defender.toString(), "#cd6767", 20, true);
});
this.setPositionInsideParent(0.5, 0.5);
if (!this.battleview.session.hasUniverse()) {
this.addActionButton(747, "Main menu", "Exit the battle and go back to the main menu", () => {
parent.exitBattle();
});
} else if (victory) {
if (this.outcome.loot.length) {
this.addActionButton(535, "Loot equipment", "Open character sheet to loot equipment from defeated fleet", () => {
let sheet = new CharacterSheet(this.view, undefined, undefined, () => {
sheet.destroy(true);
this.refreshContent();
});
sheet.show(this.player.fleet.ships[0], false);
sheet.setLoot(outcome.loot);
this.view.add.existing(sheet);
});
this.addActionButton(957, "Back to map", "Exit the battle and go back to the map", () => {
parent.exitBattle();
});
} else {
this.addActionButton(747, "Back to map", "Exit the battle and go back to the map", () => {
parent.exitBattle();
});
}
} else {
this.addActionButton(535, "Revert battle", "Go back to where the fleet was before the battle happened", () => {
parent.revertBattle();
});
this.addActionButton(957, "Main menu", "Quit the game, and go back to main menu", () => {
parent.gameui.quitGame();
});
}
}
}
}

View file

@ -63,7 +63,7 @@ module TS.SpaceTac.UI {
// Attributes and skills
attributes: { [key: string]: Phaser.Text } = {};
constructor(view: BaseView, xhidden = -2000, xshown = 0) {
constructor(view: BaseView, xhidden = -2000, xshown = 0, onclose?: Function) {
super(view.game, 0, 0, "character-sheet");
this.view = view;
@ -73,7 +73,10 @@ module TS.SpaceTac.UI {
this.xhidden = xhidden;
this.inputEnabled = true;
let close_button = new Phaser.Button(this.game, view.getWidth(), 0, "character-close", () => this.hide());
if (!onclose) {
onclose = () => this.hide();
}
let close_button = new Phaser.Button(this.game, view.getWidth(), 0, "character-close", onclose);
close_button.anchor.set(1, 0);
UIComponent.setButtonSound(close_button);
this.addChild(close_button);
@ -283,7 +286,7 @@ module TS.SpaceTac.UI {
}
if (animate) {
this.game.tweens.create(this).to({ x: this.xshown }, 800, Phaser.Easing.Circular.InOut, true);
this.game.tweens.create(this).to({ x: this.xshown }, 400, Phaser.Easing.Circular.InOut, true);
} else {
this.x = this.xshown;
}
@ -304,7 +307,7 @@ module TS.SpaceTac.UI {
this.view.audio.playOnce("ui-dialog-close");
if (animate) {
this.game.tweens.create(this).to({ x: this.xhidden }, 800, Phaser.Easing.Circular.InOut, true);
this.game.tweens.create(this).to({ x: this.xhidden }, 400, Phaser.Easing.Circular.InOut, true);
} else {
this.x = this.xhidden;
}

View file

@ -212,21 +212,21 @@ module TS.SpaceTac.UI {
/**
* Add a button in the component, positioning its center.
*/
addButton(x: number, y: number, on_click: Function, background: string, frame_normal = 0, frame_hover = 1, tooltip = "", angle = 0) {
addButton(x: number, y: number, on_click: Function, background: string, frame_normal = 0, frame_hover = 1, tooltip = ""): Phaser.Button {
let button = new Phaser.Button(this.view.game, x, y, background, on_click, undefined, frame_hover, frame_normal);
UIComponent.setButtonSound(button);
button.anchor.set(0.5, 0.5);
button.angle = angle;
if (tooltip) {
this.view.tooltip.bindStaticText(button, tooltip);
}
this.addInternalChild(button);
return button;
}
/**
* Add a static text.
*/
addText(x: number, y: number, content: string, color = "#ffffff", size = 16, bold = false, center = true, width = 0, vcenter = center): void {
addText(x: number, y: number, content: string, color = "#ffffff", size = 16, bold = false, center = true, width = 0, vcenter = center): Phaser.Text {
let style = { font: `${bold ? "bold " : ""}${size}pt SpaceTac`, fill: color, align: center ? "center" : "left" };
let text = new Phaser.Text(this.view.game, x, y, content, style);
text.anchor.set(center ? 0.5 : 0, vcenter ? 0.5 : 0);
@ -235,12 +235,15 @@ module TS.SpaceTac.UI {
text.wordWrapWidth = width;
}
this.addInternalChild(text);
return text;
}
/**
* Add a static image, positioning its center.
*
* DEPRECATED - Use addImage instead
*/
addImage(x: number, y: number, key: string, frame = 0, scale = 1): void {
addImageF(x: number, y: number, key: string, frame = 0, scale = 1): void {
let image = new Phaser.Image(this.container.game, x, y, key, frame);
image.anchor.set(0.5, 0.5);
image.scale.set(scale);
@ -250,12 +253,13 @@ module TS.SpaceTac.UI {
/**
* Add a static image, from atlases, positioning its center.
*/
addImageA(x: number, y: number, name: string, scale = 1): void {
addImage(x: number, y: number, name: string, scale = 1): Phaser.Image {
let info = this.view.getImageInfo(name);
let image = new Phaser.Image(this.container.game, x, y, info.key, info.frame);
image.anchor.set(0.5, 0.5);
image.scale.set(scale);
this.addInternalChild(image);
return image;
}
/**

View file

@ -24,7 +24,8 @@ module TS.SpaceTac.UI {
* Add a control-capturing overlay
*/
addOverlay(layer: Phaser.Group): void {
let overlay = layer.game.add.button(0, 0, "common-transparent", () => null);
let info = this.view.getImageInfo("translucent");
let overlay = layer.game.add.button(0, 0, info.key, () => null, undefined, info.frame, info.frame);
overlay.input.useHandCursor = false;
overlay.scale.set(this.view.getWidth() / overlay.width, this.view.getHeight() / overlay.height);
layer.add(overlay);

View file

@ -7,7 +7,7 @@ module TS.SpaceTac.UI {
super(view);
this.addText(this.width * 0.5, this.height * 0.3, message, "#90FEE3", 32);
this.addImage(this.width * 0.5, this.height * 0.6, "common-waiting");
this.addImageF(this.width * 0.5, this.height * 0.6, "common-waiting");
}
/**

View file

@ -43,7 +43,7 @@ module TS.SpaceTac.UI {
width -= offset;
let ioffset = style.padding + Math.floor(style.image_size / 2);
this.addImageA(ioffset, ioffset, style.image);
this.addImage(ioffset, ioffset, style.image);
if (style.image_caption) {
let text_size = Math.ceil(style.text_size * 0.6);

View file

@ -47,7 +47,7 @@ module TS.SpaceTac.UI {
let offset = 245 - active.length * spacing;
active.forEach((mission, idx) => {
let frame = mission.main ? 0 : 1;
this.addImage(35, offset + spacing * idx, "map-missions", frame);
this.addImageF(35, offset + spacing * idx, "map-missions", frame);
this.addText(90, offset + spacing * idx, mission.current_part.title, "#d2e1f3", 20, false, false, 430, true);
let location = mission.current_part.getLocationHint();

View file

@ -16,7 +16,7 @@ module TS.SpaceTac.UI {
this.clearContent();
if (title) {
this.addImage(239, 57, "map-subname");
this.addImageF(239, 57, "map-subname");
this.addText(239, 57, title, "#b8d2f1", 22, false, true);
}

View file

@ -62,7 +62,7 @@ module TS.SpaceTac.UI {
let title = mission.title;
let subtitle = `${capitalize(MissionDifficulty[mission.difficulty])} - Reward: ${mission.getRewardText()}`;
this.addImage(320, yoffset, "map-missions", 1);
this.addImageF(320, yoffset, "map-missions", 1);
if (title) {
this.addText(380, yoffset - 15, title, "#d2e1f3", 22, false, false, 620, true);
}

View file

@ -13,8 +13,9 @@ module TS.SpaceTac.UI {
constructor(parent: MainMenu) {
super(parent, 1344, 566, "menu-load-bg");
this.addButton(600, 115, () => this.paginateSave(-1), "common-arrow", 0, 0, "Scroll to newer saves", 180);
this.addButton(1038, 115, () => this.paginateSave(1), "common-arrow", 0, 0, "Scroll to older saves", 0);
let button = this.addButton(600, 115, () => this.paginateSave(-1), "common-arrow", 0, 0, "Scroll to newer saves");
button.angle = 180;
this.addButton(1038, 115, () => this.paginateSave(1), "common-arrow", 0, 0, "Scroll to older saves");
this.addButton(1224, 115, () => this.load(), "common-button-ok");
this.addButton(1224, 341, () => this.join(), "common-button-ok");