Working on end-game menu

This commit is contained in:
Dalibor Čarapić 2025-02-06 19:51:11 +01:00
parent 2e1c73c9dc
commit 93da72f55c
8 changed files with 304 additions and 89 deletions

View File

@ -3,8 +3,6 @@ import { Engine } from './Bastion';
export default class GameUIConstants { export default class GameUIConstants {
public static SidebarRect: PIXI.Rectangle; public static SidebarRect: PIXI.Rectangle;
public static ChangeRoundButtonRect: PIXI.Rectangle; public static ChangeRoundButtonRect: PIXI.Rectangle;
public static StandardDialogWidth: number;
public static StandardDialogHeight: number;
public static MaximumPlayerNameLength = 20; public static MaximumPlayerNameLength = 20;
public static init() { public static init() {
@ -15,7 +13,5 @@ export default class GameUIConstants {
Engine.app.canvas.height Engine.app.canvas.height
); );
GameUIConstants.ChangeRoundButtonRect = new PIXI.Rectangle(50, Engine.app.canvas.height - 100, 310, 100); GameUIConstants.ChangeRoundButtonRect = new PIXI.Rectangle(50, Engine.app.canvas.height - 100, 310, 100);
GameUIConstants.StandardDialogWidth = 600;
GameUIConstants.StandardDialogHeight = 800;
} }
} }

View File

@ -0,0 +1,71 @@
/**
* Handles the high score system.
*/
export class HighScoreManager {
private static readonly STORAGE_KEY_PREFIX = 'highscore_';
private static readonly MAX_SCORES = 10;
public readonly missionName: string;
private scores: PlayerScore[];
constructor(missionName: string) {
this.missionName = missionName;
this.scores = this.loadScores();
this.scores.sort((a, b) => b.score - a.score || a.timestamp - b.timestamp);
}
private loadScores(): PlayerScore[] {
const storedScores = localStorage.getItem(HighScoreManager.STORAGE_KEY_PREFIX + this.missionName);
return HighScoreManager.parseStoredScores(storedScores);
}
private saveScores(): void {
localStorage.setItem(HighScoreManager.STORAGE_KEY_PREFIX + this.missionName, JSON.stringify(this.scores));
}
public addScore(playerScore: PlayerScore): void {
this.scores.push(playerScore);
this.scores.sort((a, b) => b.score - a.score);
if (this.scores.length > HighScoreManager.MAX_SCORES) {
this.scores.length = HighScoreManager.MAX_SCORES;
}
this.saveScores();
}
public getScores(): PlayerScore[] {
return this.scores;
}
private static parseStoredScores(storedScores: string | null): PlayerScore[] {
if (!storedScores) {
return [];
}
try {
const parsedScores = JSON.parse(storedScores);
if (
Array.isArray(parsedScores) &&
parsedScores.every(
(score) =>
typeof score.playerName === 'string' &&
typeof score.score === 'number' &&
typeof score.timestamp === 'number'
)
) {
return parsedScores.map((score) => ({
playerName: score.playerName,
score: score.score,
timestamp: score.timestamp,
}));
}
} catch (e) {
console.error('Failed to parse stored scores:', e);
}
return [];
}
}
export type PlayerScore = {
playerName: string;
score: number;
timestamp: number;
};

View File

@ -8,14 +8,16 @@ import Gem from './Gem';
export default class MissionStats extends GameObject { export default class MissionStats extends GameObject {
private hp: number = 100; private hp: number = 100;
private gold: number = 0; private gold: number = 0;
private goldEarned: number = 0;
private goldSpent: number = 0;
private wavesSurvived: number = 0;
private damageDealt: number = 0;
private creepsKilled: number = 0;
private goldText: PIXI.Text; private goldText: PIXI.Text;
private healthText: PIXI.Text; private healthText: PIXI.Text;
private waveText: PIXI.Text; private waveText: PIXI.Text;
private inventory: Gem[] = []; private inventory: Gem[] = [];
// TODO: implement score keeping for leaderboards.
private score: number = 0;
public getHP() { public getHP() {
return this.hp; return this.hp;
} }
@ -147,5 +149,32 @@ export default class MissionStats extends GameObject {
}); });
} }
public getStats() {
return {
hp: this.hp,
gold: this.gold,
wavesSurvived: this.wavesSurvived,
goldEarned: this.goldEarned,
goldSpent: this.goldSpent,
score: this.calculateScore(),
};
}
private calculateScore() {
const uniqueGems = [];
for (const gem of this.inventory) {
if (!uniqueGems.includes(gem.definition.name)) {
uniqueGems.push(gem.definition.name);
}
}
return (
this.damageDealt * 2 +
this.hp * 10 +
(this.goldEarned - this.goldSpent) * 3 +
this.wavesSurvived * 100 +
uniqueGems.length * 100
);
}
public update() {} public update() {}
} }

View File

@ -4,6 +4,8 @@ import GameUIConstants from '../GameUIConstants';
import ModalDialogBase from './ModalDialog'; import ModalDialogBase from './ModalDialog';
import TextInput from './TextInput'; import TextInput from './TextInput';
import MessageBox from './MessageBox'; import MessageBox from './MessageBox';
import { HighScoreManager } from '../game/HighScoreManager';
import MissionStats from '../game/MissionStats';
export const EndGameDialogButtons = { export const EndGameDialogButtons = {
Confirm: 'OK', Confirm: 'OK',
@ -14,14 +16,18 @@ export default class EndGameDialog extends ModalDialogBase {
private dialogCaption: PIXI.Text; private dialogCaption: PIXI.Text;
private playerNameTextInput: TextInput; private playerNameTextInput: TextInput;
private lost: boolean; private lost: boolean;
private highScore: HighScoreManager;
private missionStats: MissionStats;
constructor(lost: boolean) { constructor(missionName: string, missionStats: MissionStats, lost: boolean) {
super( super(
[EndGameDialogButtons.Confirm, EndGameDialogButtons.Skip], [EndGameDialogButtons.Confirm, EndGameDialogButtons.Skip],
EndGameDialogButtons.Confirm, EndGameDialogButtons.Confirm,
EndGameDialogButtons.Skip EndGameDialogButtons.Skip
); );
this.lost = lost; this.lost = lost;
this.highScore = new HighScoreManager(missionName);
this.missionStats = missionStats;
} }
protected override generate(): void { protected override generate(): void {
@ -31,61 +37,118 @@ export default class EndGameDialog extends ModalDialogBase {
style: new PIXI.TextStyle({ style: new PIXI.TextStyle({
fill: 0xffffff, fill: 0xffffff,
fontSize: 36, fontSize: 36,
stroke: { color: 0x000000, width: 2 },
dropShadow: {
color: 0x000000,
blur: 8,
distance: 0,
},
}), }),
}); });
this.dialogContainer.addChild(this.dialogCaption);
this.dialogCaption.anchor.set(0.5, 0.5); this.dialogCaption.anchor.set(0.5, 0.5);
this.dialogCaption.x = this.dialogContainer.width / 2; this.dialogCaption.x = this.dialogContainer.width / 2;
this.dialogCaption.y = 50; this.dialogCaption.y = 50;
this.dialogContainer.addChild(this.dialogCaption);
} }
protected override createDialogBackground(width: number, height: number): PIXI.Container { protected override createDialogBackground(): PIXI.NineSliceSprite {
const background = new PIXI.NineSliceSprite({ return new PIXI.NineSliceSprite({
texture: GameAssets.EndScreenDialog, texture: GameAssets.EndScreenDialog,
leftWidth: 50, leftWidth: 50,
topHeight: 100, topHeight: 100,
rightWidth: 50, rightWidth: 50,
bottomHeight: 50, bottomHeight: 50,
}); });
background.x = 0;
background.y = 0;
background.width = width;
background.height = height;
return background;
} }
protected override createContent(): PIXI.Container { protected override createContent(): PIXI.Container {
const container = new PIXI.Container(); const container = new PIXI.Container();
const caption = new PIXI.Text({ const lineHeight = 35;
text: 'Enter your name:', const lblScore = this.createText('Mission details:', '#fee', true);
style: new PIXI.TextStyle({ container.addChild(lblScore);
fill: 0xffffff, const stats = this.missionStats.getStats();
fontSize: 24, const width = this.getWidth() - this.background.leftWidth - this.background.rightWidth - 20;
}), const labels = [
}); this.createText('HP:'),
container.addChild(caption); this.createText('Gold:'),
this.playerNameTextInput = new TextInput( this.createText('Waves Survived:'),
GameUIConstants.MaximumPlayerNameLength * 20, this.createText('Gold Earned:'),
GameUIConstants.MaximumPlayerNameLength this.createText('Gold Spent:'),
); this.createText('----'),
this.playerNameTextInput.container.y = caption.height + 10; this.createText('Score:'),
];
const values = [
this.createText(stats.hp.toString(), 'yellow'),
this.createText(stats.gold.toString(), 'yellow'),
this.createText(stats.wavesSurvived.toString(), 'yellow'),
this.createText(stats.goldEarned.toString(), 'yellow'),
this.createText(stats.goldSpent.toString(), 'yellow'),
this.createText('----', 'yellow'),
this.createText(stats.score.toString(), 'yellow'),
];
const valueX = 300;
for (let i = 0; i < labels.length; i++) {
if (labels[i].text === '----') {
const line = new PIXI.Graphics();
const y = lblScore.y + lblScore.height + 10 + i * lineHeight + lineHeight / 2;
line.moveTo(10, y);
line.lineTo(width, y);
line.stroke({ color: 'yellow', width: 2 });
container.addChild(line);
} else {
labels[i].x = 10;
labels[i].y = lblScore.y + lblScore.height + 10 + i * lineHeight;
container.addChild(labels[i]);
values[i].x = valueX;
values[i].y = lblScore.y + lblScore.height + 10 + i * lineHeight;
container.addChild(values[i]);
}
}
const offsetY = values[values.length - 1].y + lineHeight + 80;
const lblName = this.createText('Enter your name:');
lblName.y = offsetY;
container.addChild(lblName);
this.playerNameTextInput = new TextInput(width, GameUIConstants.MaximumPlayerNameLength);
this.playerNameTextInput.container.y = lblName.y + lblName.height + 10;
container.addChild(this.playerNameTextInput.container); container.addChild(this.playerNameTextInput.container);
return container; return container;
} }
override close(button?: string): void { override close(button?: string): void {
if (button === EndGameDialogButtons.Confirm && this.playerNameTextInput.getText().length == 0) { if (button === EndGameDialogButtons.Confirm) {
if (this.playerNameTextInput.getText().length == 0) {
MessageBox.show('Please enter your name.', ['OK']); MessageBox.show('Please enter your name.', ['OK']);
} else {
this.highScore.addScore({
playerName: this.playerNameTextInput.getText(),
score: this.missionStats.getStats().score,
timestamp: Date.now(),
});
super.close(button);
}
} else { } else {
super.close(button); super.close(button);
} }
} }
private createText(caption: string, color: string = '#fff', bold = false): PIXI.Text {
return new PIXI.Text({
text: caption,
style: new PIXI.TextStyle({
fill: color,
fontSize: 24,
fontWeight: bold ? 'bold' : 'normal',
}),
});
}
protected override getWidth(): number | undefined { protected override getWidth(): number | undefined {
return GameUIConstants.StandardDialogWidth; return 600;
} }
protected override getHeight(): number | undefined { protected override getHeight(): number | undefined {
return GameUIConstants.StandardDialogHeight; return 800;
} }
} }

View File

@ -1,8 +1,7 @@
import * as PIXI from 'pixi.js'; import * as PIXI from 'pixi.js';
import GameAssets from '../Assets'; import GameAssets from '../Assets';
import GameUIConstants from '../GameUIConstants';
import ModalDialogBase from './ModalDialog'; import ModalDialogBase from './ModalDialog';
import TextInput from './TextInput'; import { HighScoreManager } from '../game/HighScoreManager';
export const HighScoreDialogButtons = { export const HighScoreDialogButtons = {
Retry: 'Retry', Retry: 'Retry',
@ -12,10 +11,9 @@ export const HighScoreDialogButtons = {
export default class HighScoreDialog extends ModalDialogBase { export default class HighScoreDialog extends ModalDialogBase {
private dialogCaption: PIXI.Text; private dialogCaption: PIXI.Text;
private playerNameTextInput: TextInput; private highScore: HighScoreManager;
private lost: boolean;
constructor(nextMissionAvailable: boolean) { constructor(missionName: string, nextMissionAvailable: boolean) {
super( super(
nextMissionAvailable nextMissionAvailable
? [HighScoreDialogButtons.Retry, HighScoreDialogButtons.NextMission, HighScoreDialogButtons.MainMenu] ? [HighScoreDialogButtons.Retry, HighScoreDialogButtons.NextMission, HighScoreDialogButtons.MainMenu]
@ -23,6 +21,7 @@ export default class HighScoreDialog extends ModalDialogBase {
nextMissionAvailable ? HighScoreDialogButtons.NextMission : HighScoreDialogButtons.Retry, nextMissionAvailable ? HighScoreDialogButtons.NextMission : HighScoreDialogButtons.Retry,
HighScoreDialogButtons.MainMenu HighScoreDialogButtons.MainMenu
); );
this.highScore = new HighScoreManager(missionName);
} }
protected override generate(): void { protected override generate(): void {
@ -32,47 +31,86 @@ export default class HighScoreDialog extends ModalDialogBase {
style: new PIXI.TextStyle({ style: new PIXI.TextStyle({
fill: 0xffffff, fill: 0xffffff,
fontSize: 36, fontSize: 36,
stroke: { color: 0x000000, width: 2 },
dropShadow: {
color: 0x000000,
blur: 8,
distance: 0,
},
}), }),
}); });
this.dialogContainer.addChild(this.dialogCaption);
this.dialogCaption.anchor.set(0.5, 0.5); this.dialogCaption.anchor.set(0.5, 0.5);
this.dialogCaption.x = this.dialogContainer.width / 2; this.dialogCaption.x = this.dialogContainer.width / 2;
this.dialogCaption.y = 50; this.dialogCaption.y = 50;
this.dialogContainer.addChild(this.dialogCaption);
} }
protected override createDialogBackground(width: number, height: number): PIXI.Container { protected override createDialogBackground(): PIXI.NineSliceSprite {
const background = new PIXI.NineSliceSprite({ return new PIXI.NineSliceSprite({
texture: GameAssets.EndScreenDialog, texture: GameAssets.EndScreenDialog,
leftWidth: 50, leftWidth: 50,
topHeight: 100, topHeight: 100,
rightWidth: 50, rightWidth: 50,
bottomHeight: 50, bottomHeight: 50,
}); });
background.x = 0;
background.y = 0;
background.width = width;
background.height = height;
return background;
} }
protected override createContent(): PIXI.Container { protected override createContent(): PIXI.Container {
const container = new PIXI.Container(); const container = new PIXI.Container();
const caption = new PIXI.Text({ const caption = this.createText('Mission: ' + this.highScore.missionName, '#fee', true);
text: 'Leaderboard:',
style: new PIXI.TextStyle({
fill: 0xffffff,
fontSize: 24,
}),
});
container.addChild(caption); container.addChild(caption);
const lineHeight = 35;
const scores = this.highScore.getScores();
while (scores.length < 10) {
scores.push({ playerName: '---', score: 0, timestamp: 0 });
}
const numberTexts = [
this.createText('#', '#fee'),
...scores.map((_, i) => this.createText((i + 1).toString())),
];
const playerTexts = [
this.createText('Player', '#fee', true),
...scores.map((score) => this.createText(score.playerName)),
];
const scoreTexts = [
this.createText('Score', '#fee', true),
...scores.map((score) => this.createText(score.score.toString())),
];
const playerX = numberTexts.reduce((maxX, text) => Math.max(maxX, text.width), 0) + 20;
const scoreX = playerX + playerTexts.reduce((maxX, text) => Math.max(maxX, text.width), 0) + 20;
for (let i = 0; i < playerTexts.length; i++) {
numberTexts[i].x = 10;
numberTexts[i].y = lineHeight + 10 + i * lineHeight;
container.addChild(numberTexts[i]);
playerTexts[i].x = playerX;
playerTexts[i].y = lineHeight + 10 + i * lineHeight;
container.addChild(playerTexts[i]);
scoreTexts[i].x = scoreX;
scoreTexts[i].y = lineHeight + 10 + i * lineHeight;
container.addChild(scoreTexts[i]);
}
return container; return container;
} }
private createText(caption: string, color: string = '#fff', bold = false): PIXI.Text {
return new PIXI.Text({
text: caption,
style: new PIXI.TextStyle({
fill: color,
fontSize: 24,
fontWeight: bold ? 'bold' : 'normal',
}),
});
}
protected override getWidth(): number | undefined { protected override getWidth(): number | undefined {
return GameUIConstants.StandardDialogWidth; return 600;
} }
protected override getHeight(): number | undefined { protected override getHeight(): number | undefined {
return GameUIConstants.StandardDialogHeight; return 800;
} }
} }

View File

@ -8,15 +8,12 @@ import KeyboardManager from '../game/KeyboardManager';
export default abstract class ModalDialogBase extends GuiObject { export default abstract class ModalDialogBase extends GuiObject {
protected overlay: PIXI.Graphics; protected overlay: PIXI.Graphics;
protected dialogPadding = 40; protected buttonHeight = 65;
protected contentPadding = 10;
protected buttonPadding = 10;
protected buttonAreaHeight = 40;
protected buttonHeight = 60;
protected buttonCaptions: string[]; protected buttonCaptions: string[];
protected buttons: Button[] = []; protected buttons: Button[] = [];
protected dialogContent: PIXI.Container; protected dialogContent: PIXI.Container;
protected dialogContainer: PIXI.Container; protected dialogContainer: PIXI.Container;
protected background: PIXI.NineSliceSprite;
private generated = false; private generated = false;
private escapeKeyButton?: string | null; private escapeKeyButton?: string | null;
@ -43,8 +40,14 @@ export default abstract class ModalDialogBase extends GuiObject {
*/ */
public show(): Promise<string | null> { public show(): Promise<string | null> {
this.generate(); this.generate();
const dialogBounds = `x: ${Math.round(this.dialogContainer.x)}, y: ${Math.round(
this.dialogContainer.y
)}, width: ${Math.round(this.dialogContainer.width)}, height: ${Math.round(this.dialogContainer.height)}`;
const contentBounds = `x: ${Math.round(this.dialogContent.x)}, y: ${Math.round(
this.dialogContent.y
)}, width: ${Math.round(this.dialogContent.width)}, height: ${Math.round(this.dialogContent.height)}`;
console.debug( console.debug(
`ModalDialogBase.show(content: ${this.dialogContainer.width}x${this.dialogContainer.height}, buttons: ${this.buttonCaptions})` `ModalDialogBase.show(dialog: ${dialogBounds}, content: ${contentBounds}, buttons: ${this.buttonCaptions})`
); );
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
Engine.app.stage.addChild(this.container); Engine.app.stage.addChild(this.container);
@ -69,19 +72,14 @@ export default abstract class ModalDialogBase extends GuiObject {
/** /**
* Creates dialog background. * Creates dialog background.
*/ */
protected createDialogBackground(width: number, height: number): PIXI.Container { protected createDialogBackground(): PIXI.NineSliceSprite {
const background = new PIXI.NineSliceSprite({ return new PIXI.NineSliceSprite({
texture: GameAssets.Frame04Texture, texture: GameAssets.Frame04Texture,
leftWidth: 60, leftWidth: 60,
topHeight: 60, topHeight: 60,
rightWidth: 60, rightWidth: 60,
bottomHeight: 60, bottomHeight: 60,
}); });
background.x = 0;
background.y = 0;
background.width = width;
background.height = height;
return background;
} }
/** /**
@ -110,23 +108,31 @@ export default abstract class ModalDialogBase extends GuiObject {
// Prevent interaction with the underlying scene // Prevent interaction with the underlying scene
this.overlay.interactive = true; this.overlay.interactive = true;
this.container.addChild(this.overlay); this.container.addChild(this.overlay);
this.dialogContent = this.createContent();
const buttonDefs = this.buttonCaptions.map((btnCaption) => ({ const buttonDefs = this.buttonCaptions.map((btnCaption) => ({
caption: btnCaption, caption: btnCaption,
width: btnCaption.length * 16 + 40, width: btnCaption.length * 14 + 60,
height: this.buttonHeight, height: this.buttonHeight,
click: () => this.close(btnCaption), click: () => this.close(btnCaption),
})); }));
this.background = this.createDialogBackground();
this.dialogContent = this.createContent();
let buttonTotalWidth = 0; let buttonTotalWidth = 0;
for (const buttonDef of buttonDefs) { for (const buttonDef of buttonDefs) {
if (buttonTotalWidth > 0) buttonTotalWidth += this.buttonPadding; if (buttonTotalWidth > 0) buttonTotalWidth += 10;
buttonTotalWidth += buttonDef.width; buttonTotalWidth += buttonDef.width;
} }
const contentWidth = this.dialogContent.width + this.contentPadding * 2; const buttonAreaHeight = this.buttonCaptions.length > 0 ? this.buttonHeight + 10 : 0;
const contentHeight = this.dialogContent.height + this.contentPadding * 2;
let width = this.getWidth() || Math.max(buttonTotalWidth, contentWidth) + this.dialogPadding * 2; let width =
let height = this.getHeight() || contentHeight + this.buttonAreaHeight + this.dialogPadding * 2; this.getWidth() ||
Math.max(buttonTotalWidth, this.dialogContent.width) +
this.background.leftWidth +
this.background.rightWidth;
let height =
this.getHeight() ||
this.dialogContent.height + buttonAreaHeight + this.background.topHeight + this.background.bottomHeight;
const modalBounds = new PIXI.Rectangle( const modalBounds = new PIXI.Rectangle(
Engine.app.canvas.width / 2 - width / 2, Engine.app.canvas.width / 2 - width / 2,
Engine.app.canvas.height / 2 - height / 2, Engine.app.canvas.height / 2 - height / 2,
@ -137,14 +143,24 @@ export default abstract class ModalDialogBase extends GuiObject {
this.dialogContainer = new PIXI.Container(); this.dialogContainer = new PIXI.Container();
this.dialogContainer.x = modalBounds.x; this.dialogContainer.x = modalBounds.x;
this.dialogContainer.y = modalBounds.y; this.dialogContainer.y = modalBounds.y;
this.background.width = width;
this.background.height = height;
this.dialogContainer.addChild(this.background);
const background = this.createDialogBackground(modalBounds.width, modalBounds.height); if (this.dialogContent.width < modalBounds.width) {
this.dialogContainer.addChild(background);
if (this.dialogContent.width < modalBounds.width)
this.dialogContent.x = modalBounds.width / 2 - this.dialogContent.width / 2; this.dialogContent.x = modalBounds.width / 2 - this.dialogContent.width / 2;
if (this.dialogContent.height < modalBounds.height - this.buttonAreaHeight) }
this.dialogContent.y = (modalBounds.height - this.buttonAreaHeight) / 2 - this.dialogContent.height / 2; if (
this.dialogContent.height <
modalBounds.height - buttonAreaHeight - this.background.topHeight - this.background.bottomHeight
) {
this.dialogContent.y =
this.background.topHeight +
(modalBounds.height - buttonAreaHeight - this.background.topHeight - this.background.bottomHeight) / 2 -
this.dialogContent.height / 2;
} else {
this.dialogContent.y = this.background.topHeight;
}
this.dialogContainer.addChild(this.dialogContent); this.dialogContainer.addChild(this.dialogContent);
let buttonXPos = modalBounds.width / 2 - buttonTotalWidth / 2; let buttonXPos = modalBounds.width / 2 - buttonTotalWidth / 2;
@ -152,7 +168,7 @@ export default abstract class ModalDialogBase extends GuiObject {
const button = new Button( const button = new Button(
new PIXI.Rectangle( new PIXI.Rectangle(
buttonXPos, buttonXPos,
modalBounds.height - this.buttonAreaHeight - this.dialogPadding, modalBounds.height - this.buttonHeight - this.background.bottomHeight,
buttonDef.width, buttonDef.width,
buttonDef.height buttonDef.height
), ),
@ -162,7 +178,7 @@ export default abstract class ModalDialogBase extends GuiObject {
button.onClick = buttonDef.click; button.onClick = buttonDef.click;
this.buttons.push(button); this.buttons.push(button);
this.dialogContainer.addChild(button.container); this.dialogContainer.addChild(button.container);
buttonXPos += buttonDef.width + this.buttonPadding; buttonXPos += buttonDef.width + 10;
} }
this.container.addChild(this.dialogContainer); this.container.addChild(this.dialogContainer);
} }

View File

@ -27,7 +27,7 @@ export default class TextInput extends GuiObject {
this.backgroundSprite.x = 0; this.backgroundSprite.x = 0;
this.backgroundSprite.y = 0; this.backgroundSprite.y = 0;
this.backgroundSprite.width = width; this.backgroundSprite.width = width;
this.backgroundSprite.height = 60; this.backgroundSprite.height = 80;
this.container.addChild(this.backgroundSprite); this.container.addChild(this.backgroundSprite);
this.text = new PIXI.Text({ this.text = new PIXI.Text({
text: '', text: '',
@ -36,8 +36,8 @@ export default class TextInput extends GuiObject {
fontSize: 24, fontSize: 24,
}), }),
}); });
this.text.x = 20; this.text.x = 30;
this.text.y = 20; this.text.y = 25;
this.container.addChild(this.text); this.container.addChild(this.text);
this.keyboardManagerUnsubscribe = KeyboardManager.onKeyPressed(this.onKeyPress.bind(this)); this.keyboardManagerUnsubscribe = KeyboardManager.onKeyPressed(this.onKeyPress.bind(this));
} }

View File

@ -245,15 +245,17 @@ export class GameScene extends Scene {
} }
private async ShowEndgameDialog(lost) { private async ShowEndgameDialog(lost) {
const endGameDialog = new EndGameDialog(lost); const endGameDialog = new EndGameDialog(this.mission.name, this.MissionStats, lost);
await endGameDialog.show(); await endGameDialog.show();
const highScore = new HighScoreDialog(this.missionIndex + 1 < GameAssets.Missions.length); const highScore = new HighScoreDialog(this.mission.name, this.missionIndex + 1 < GameAssets.Missions.length);
const result = await highScore.show(); const result = await highScore.show();
if (result === HighScoreDialogButtons.MainMenu) { if (result === HighScoreDialogButtons.MainMenu) {
this.ReturnToMain(); this.ReturnToMain();
} else if (result === HighScoreDialogButtons.NextMission) { } else if (result === HighScoreDialogButtons.NextMission) {
this.destroy();
Engine.GameMaster.changeScene(new GameScene(GameAssets.Missions[this.missionIndex + 1].name)); Engine.GameMaster.changeScene(new GameScene(GameAssets.Missions[this.missionIndex + 1].name));
} else if (result === HighScoreDialogButtons.Retry) { } else if (result === HighScoreDialogButtons.Retry) {
this.destroy();
Engine.GameMaster.changeScene(new GameScene(this.mission.name)); Engine.GameMaster.changeScene(new GameScene(this.mission.name));
} }
} }