Initial commit
This commit is contained in:
commit
2f17903d30
8188 files changed
+7877857
No files matched your search
@@ -0,0 +1,12 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { Mode } from "./ui";
|
||||
import UiHandler from "./uiHandler";
|
||||
|
||||
export default abstract class AwaitableUiHandler extends UiHandler {
|
||||
protected awaitingActionInput: boolean;
|
||||
protected onActionInput: Function;
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode) {
|
||||
super(scene, mode);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { addTextObject, TextStyle } from "../text";
|
||||
import UI, { Mode } from "./ui";
|
||||
import * as Utils from "../utils";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import { getStatName, Stat } from "../pokemon-stat";
|
||||
|
||||
export default class BattleMessageUiHandler extends MessageUiHandler {
|
||||
private levelUpStatsContainer: Phaser.GameObjects.Container;
|
||||
private levelUpStatsIncrContent: Phaser.GameObjects.Text;
|
||||
private levelUpStatsValuesContent: Phaser.GameObjects.Text;
|
||||
|
||||
public bg: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.MESSAGE);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
this.textTimer = null;
|
||||
this.textCallbackTimer = null;
|
||||
|
||||
const bg = this.scene.add.image(0, 0, 'bg');
|
||||
bg.setOrigin(0, 1);
|
||||
ui.add(bg);
|
||||
|
||||
this.bg = bg;
|
||||
|
||||
const messageContainer = this.scene.add.container(12, -39);
|
||||
ui.add(messageContainer);
|
||||
|
||||
const message = addTextObject(this.scene, 0, 0, '', TextStyle.MESSAGE, {
|
||||
maxLines: 2,
|
||||
wordWrap: {
|
||||
width: 1780
|
||||
}
|
||||
});
|
||||
messageContainer.add(message);
|
||||
|
||||
this.message = message;
|
||||
|
||||
const prompt = this.scene.add.sprite(0, 0, 'prompt');
|
||||
prompt.setVisible(false);
|
||||
prompt.setOrigin(0, 0);
|
||||
messageContainer.add(prompt);
|
||||
|
||||
this.prompt = prompt;
|
||||
|
||||
const levelUpStatsContainer = this.scene.add.container(0, 0);
|
||||
levelUpStatsContainer.setVisible(false);
|
||||
ui.add(levelUpStatsContainer);
|
||||
|
||||
this.levelUpStatsContainer = levelUpStatsContainer;
|
||||
|
||||
const levelUpStatsBg = this.scene.add.image((this.scene.game.canvas.width / 6), -100, 'level_up_stats');
|
||||
levelUpStatsBg.setOrigin(1, 0);
|
||||
levelUpStatsContainer.add(levelUpStatsBg);
|
||||
|
||||
const levelUpStatsLabelsContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 111, -94, '', TextStyle.WINDOW, { maxLines: 6 });
|
||||
let levelUpStatsLabelText = '';
|
||||
|
||||
const stats = Utils.getEnumValues(Stat);
|
||||
for (let s of stats)
|
||||
levelUpStatsLabelText += `${getStatName(s)}\n`;
|
||||
|
||||
levelUpStatsLabelsContent.text = levelUpStatsLabelText;
|
||||
levelUpStatsContainer.add(levelUpStatsLabelsContent);
|
||||
|
||||
const levelUpStatsIncrContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 50, -94, '+\n+\n+\n+\n+\n+', TextStyle.WINDOW, { maxLines: 6 });
|
||||
levelUpStatsContainer.add(levelUpStatsIncrContent);
|
||||
|
||||
this.levelUpStatsIncrContent = levelUpStatsIncrContent;
|
||||
|
||||
const levelUpStatsValuesContent = addTextObject(this.scene, (this.scene.game.canvas.width / 6) - 7, -94, '', TextStyle.WINDOW, { maxLines: 6 });
|
||||
levelUpStatsValuesContent.setOrigin(1, 0);
|
||||
levelUpStatsContainer.add(levelUpStatsValuesContent);
|
||||
|
||||
this.levelUpStatsValuesContent = levelUpStatsValuesContent;
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
super.show(args);
|
||||
|
||||
this.bg.setTexture('bg');
|
||||
this.message.setWordWrapWidth(1780);
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
const ui = this.getUi();
|
||||
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
|
||||
if (this.awaitingActionInput) {
|
||||
if (keyCode === keyCodes.X || keyCode === keyCodes.Z) {
|
||||
if (this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
}
|
||||
|
||||
promptLevelUpStats(prevStats: integer[], showTotals: boolean, callback?: Function) {
|
||||
const newStats = (this.scene as BattleScene).getPlayerPokemon().stats;
|
||||
let levelUpStatsValuesText = '';
|
||||
const stats = Utils.getEnumValues(Stat);
|
||||
for (let s of stats)
|
||||
levelUpStatsValuesText += `${showTotals ? newStats[s] : newStats[s] - prevStats[s]}\n`;
|
||||
this.levelUpStatsValuesContent.text = levelUpStatsValuesText;
|
||||
this.levelUpStatsIncrContent.setVisible(!showTotals);
|
||||
this.levelUpStatsContainer.setVisible(true);
|
||||
this.awaitingActionInput = true;
|
||||
this.onActionInput = () => {
|
||||
if (!showTotals)
|
||||
this.promptLevelUpStats(null, true, callback);
|
||||
else {
|
||||
this.levelUpStatsContainer.setVisible(false);
|
||||
if (callback)
|
||||
callback();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import { CommandPhase } from "../battle-phase";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { addTextObject, TextStyle } from "../text";
|
||||
import { toPokemonUpperCase } from "../utils";
|
||||
import UI, { Mode } from "./ui";
|
||||
import UiHandler from "./uiHandler";
|
||||
|
||||
export enum Command {
|
||||
FIGHT = 0,
|
||||
BALL,
|
||||
POKEMON,
|
||||
RUN
|
||||
};
|
||||
|
||||
export default class CommandUiHandler extends UiHandler {
|
||||
private commandsContainer: Phaser.GameObjects.Container;
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.COMMAND);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
const commands = [ 'Fight', 'Ball', 'Pokémon', 'Run' ].map(s => toPokemonUpperCase(s));
|
||||
|
||||
this.commandsContainer = this.scene.add.container(216, -38.7);
|
||||
this.commandsContainer.setVisible(false);
|
||||
ui.add(this.commandsContainer);
|
||||
|
||||
for (let c = 0; c < commands.length; c++) {
|
||||
const commandText = addTextObject(this.scene, c % 2 === 0 ? 0 : 55.8, c < 2 ? 0 : 16, commands[c], TextStyle.WINDOW);
|
||||
this.commandsContainer.add(commandText);
|
||||
}
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
super.show(args);
|
||||
|
||||
this.commandsContainer.setVisible(true);
|
||||
|
||||
const messageHandler = this.getUi().getMessageHandler();
|
||||
messageHandler.bg.setTexture('bg_command');
|
||||
messageHandler.message.setWordWrapWidth(1110);
|
||||
messageHandler.showText(`What will\n${(this.scene as BattleScene).getPlayerPokemon().name} do?`, 0);
|
||||
this.setCursor(this.cursor);
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
|
||||
const ui = this.getUi();
|
||||
|
||||
let success = false;
|
||||
|
||||
if (keyCode === keyCodes.X || keyCode === keyCodes.Z) {
|
||||
|
||||
if (keyCode === keyCodes.Z) {
|
||||
switch (this.cursor) {
|
||||
case 0:
|
||||
ui.setMode(Mode.FIGHT);
|
||||
success = true;
|
||||
break;
|
||||
case 1:
|
||||
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.BALL, this.cursor);
|
||||
success = true;
|
||||
break;
|
||||
case 2:
|
||||
ui.setMode(Mode.PARTY);
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
case keyCodes.UP:
|
||||
if (this.cursor >= 2)
|
||||
success = this.setCursor(this.cursor - 2);
|
||||
break;
|
||||
case keyCodes.DOWN:
|
||||
if (this.cursor < 2)
|
||||
success = this.setCursor(this.cursor + 2);
|
||||
break;
|
||||
case keyCodes.LEFT:
|
||||
if (this.cursor % 2 === 1)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
break;
|
||||
case keyCodes.RIGHT:
|
||||
if (this.cursor % 2 === 0)
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ui = this.getUi();
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
|
||||
ui.add(this.cursorObj);
|
||||
}
|
||||
|
||||
this.cursorObj.setPosition(211 + (cursor % 2 === 1 ? 56 : 0), -31 + (cursor >= 2 ? 16 : 0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.commandsContainer.setVisible(false);
|
||||
this.getUi().getMessageHandler().clearText();
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj)
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
import { CommandPhase } from "../battle-phase";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { addTextObject, TextStyle } from "../text";
|
||||
import { Command } from "./command-ui-handler";
|
||||
import BattleMessageUiHandler from "./battle-message-ui-handler";
|
||||
import UI, { Mode } from "./ui";
|
||||
import UiHandler from "./uiHandler";
|
||||
|
||||
export default class FightUiHandler extends UiHandler {
|
||||
private movesContainer: Phaser.GameObjects.Container;
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.FIGHT);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
const movesContainer = this.scene.add.container(18, -38.7);
|
||||
ui.add(movesContainer);
|
||||
|
||||
this.movesContainer = movesContainer;
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
super.show(args);
|
||||
|
||||
const messageHandler = this.getUi().getMessageHandler();
|
||||
messageHandler.bg.setTexture('bg_fight');
|
||||
this.setCursor(this.cursor);
|
||||
this.displayMoves();
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
const ui = this.getUi();
|
||||
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
|
||||
|
||||
let success = false;
|
||||
|
||||
if (keyCode === keyCodes.X || keyCode === keyCodes.Z) {
|
||||
if (keyCode === keyCodes.Z) {
|
||||
if (((this.scene as BattleScene).getCurrentPhase() as CommandPhase).handleCommand(Command.FIGHT, this.cursor))
|
||||
success = true;
|
||||
} else {
|
||||
ui.setMode(Mode.COMMAND);
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
case keyCodes.UP:
|
||||
if (this.cursor >= 2)
|
||||
success = this.setCursor(this.cursor - 2);
|
||||
break;
|
||||
case keyCodes.DOWN:
|
||||
if (this.cursor < 2)
|
||||
success = this.setCursor(this.cursor + 2);
|
||||
break;
|
||||
case keyCodes.LEFT:
|
||||
if (this.cursor % 2 === 1)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
break;
|
||||
case keyCodes.RIGHT:
|
||||
if (this.cursor % 2 === 0)
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ui = this.getUi();
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
|
||||
ui.add(this.cursorObj);
|
||||
}
|
||||
|
||||
this.cursorObj.setPosition(13 + (cursor % 2 === 1 ? 100 : 0), -31 + (cursor >= 2 ? 15 : 0));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
displayMoves() {
|
||||
const moveset = (this.scene as BattleScene).getPlayerPokemon().moveset;
|
||||
for (let m = 0; m < 4; m++) {
|
||||
const moveText = addTextObject(this.scene, m % 2 === 0 ? 0 : 100, m < 2 ? 0 : 16, '-', TextStyle.WINDOW);
|
||||
if (m < moveset.length)
|
||||
moveText.setText(moveset[m].getName());
|
||||
this.movesContainer.add(moveText);
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.clearMoves();
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
clearMoves() {
|
||||
this.movesContainer.removeAll(true);
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj)
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import AwaitableUiHandler from "./awaitable-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default abstract class MessageUiHandler extends AwaitableUiHandler {
|
||||
protected textTimer: Phaser.Time.TimerEvent;
|
||||
protected textCallbackTimer: Phaser.Time.TimerEvent;
|
||||
protected pendingPrompt: boolean;
|
||||
|
||||
public message: Phaser.GameObjects.Text;
|
||||
public prompt: Phaser.GameObjects.Sprite;
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode) {
|
||||
super(scene, mode);
|
||||
|
||||
this.pendingPrompt = false;
|
||||
}
|
||||
|
||||
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean) {
|
||||
if (delay === null || delay === undefined)
|
||||
delay = 20;
|
||||
if (this.textTimer) {
|
||||
this.textTimer.remove();
|
||||
if (this.textCallbackTimer)
|
||||
this.textCallbackTimer.callback();
|
||||
};
|
||||
if (prompt) {
|
||||
const originalCallback = callback;
|
||||
callback = () => {
|
||||
const wrappedTextLines = this.message.runWordWrap(this.message.text).split(/\n/g);
|
||||
const textLinesCount = wrappedTextLines.length;
|
||||
const lastTextLine = wrappedTextLines[wrappedTextLines.length - 1];
|
||||
const lastLineTest = this.scene.add.text(0, 0, lastTextLine, { font: '96px emerald' });
|
||||
lastLineTest.setScale(this.message.scale);
|
||||
const lastLineWidth = lastLineTest.displayWidth;
|
||||
lastLineTest.destroy();
|
||||
if (prompt) {
|
||||
if (this.prompt) {
|
||||
this.prompt.setPosition(lastLineWidth + 2, (textLinesCount - 1) * 18 + 2);
|
||||
this.prompt.play('prompt');
|
||||
}
|
||||
this.pendingPrompt = false;
|
||||
}
|
||||
this.awaitingActionInput = true;
|
||||
this.onActionInput = () => {
|
||||
if (this.prompt) {
|
||||
this.prompt.anims.stop();
|
||||
this.prompt.setVisible(false);
|
||||
}
|
||||
if (originalCallback) {
|
||||
if (callbackDelay) {
|
||||
this.textCallbackTimer = this.scene.time.delayedCall(callbackDelay, () => {
|
||||
if (this.textCallbackTimer) {
|
||||
this.textCallbackTimer.destroy();
|
||||
this.textCallbackTimer = null;
|
||||
}
|
||||
originalCallback();
|
||||
});
|
||||
} else
|
||||
originalCallback();
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
if (delay) {
|
||||
this.clearText();
|
||||
if (prompt)
|
||||
this.pendingPrompt = true;
|
||||
this.textTimer = this.scene.time.addEvent({
|
||||
delay: delay,
|
||||
callback: () => {
|
||||
this.message.setText(text.slice(0, text.length - this.textTimer.repeatCount));
|
||||
if (callback && !this.textTimer.repeatCount) {
|
||||
if (callbackDelay && !prompt) {
|
||||
this.textCallbackTimer = this.scene.time.delayedCall(callbackDelay, () => {
|
||||
if (this.textCallbackTimer) {
|
||||
this.textCallbackTimer.destroy();
|
||||
this.textCallbackTimer = null;
|
||||
}
|
||||
callback();
|
||||
});
|
||||
} else
|
||||
callback();
|
||||
}
|
||||
},
|
||||
repeat: text.length
|
||||
});
|
||||
} else {
|
||||
this.message.setText(text);
|
||||
if (prompt)
|
||||
this.pendingPrompt = true;
|
||||
if (callback)
|
||||
callback();
|
||||
}
|
||||
}
|
||||
|
||||
clearText() {
|
||||
this.message.setText('');
|
||||
this.pendingPrompt = false;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import { Modifier } from "../modifier";
|
||||
|
||||
@@ -0,0 +1,290 @@
|
||||
import { SwitchPhase, SwitchSummonPhase } from "../battle-phase";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { ModifierTier, ModifierType } from "../modifier";
|
||||
import { getPokeballAtlasKey, PokeballType } from "../pokeball";
|
||||
import { addTextObject, TextStyle } from "../text";
|
||||
import AwaitableUiHandler from "./awaitable-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default class ModifierSelectUiHandler extends AwaitableUiHandler {
|
||||
private overlayBg: Phaser.GameObjects.Rectangle;
|
||||
private modifierContainer: Phaser.GameObjects.Container;
|
||||
private options: ModifierOption[];
|
||||
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.SWITCH_CHECK);
|
||||
|
||||
this.options = [];
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
const overlayWidth = this.scene.game.canvas.width / 6;
|
||||
const overlayHeight = (this.scene.game.canvas.height / 6) - 48;
|
||||
this.overlayBg = this.scene.add.rectangle(0, overlayHeight * -1 - 48, overlayWidth, overlayHeight, 0x424242);
|
||||
this.overlayBg.setOrigin(0, 0);
|
||||
this.overlayBg.setAlpha(0);
|
||||
ui.add(this.overlayBg);
|
||||
|
||||
this.modifierContainer = this.scene.add.container(0, 0);
|
||||
ui.add(this.modifierContainer);
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
if (this.active || args.length !== 2 || !(args[0] instanceof Array) || !args[0].length || !(args[1] instanceof Function))
|
||||
return;
|
||||
|
||||
super.show(args);
|
||||
|
||||
this.getUi().clearText();
|
||||
|
||||
const types = args[0] as ModifierType[];
|
||||
for (let m = 0; m < types.length; m++) {
|
||||
const sliceWidth = (this.scene.game.canvas.width / 6) / (types.length + 2);
|
||||
const option = new ModifierOption(this.scene, sliceWidth * (m + 1) + (sliceWidth * 0.5), -this.scene.game.canvas.height / 12 - 24, types[m]);
|
||||
option.setScale(0.5);
|
||||
this.scene.add.existing(option);
|
||||
this.modifierContainer.add(option);
|
||||
this.options.push(option);
|
||||
}
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.overlayBg,
|
||||
alpha: 0.5,
|
||||
ease: 'Sine.easeOut',
|
||||
duration: 750
|
||||
});
|
||||
|
||||
let i = 0;
|
||||
|
||||
this.scene.tweens.addCounter({
|
||||
ease: 'Sine.easeIn',
|
||||
duration: 1250,
|
||||
onUpdate: t => {
|
||||
const value = t.getValue();
|
||||
const index = Math.floor(value * types.length);
|
||||
if (index > i && index <= types.length)
|
||||
this.options[i++].show(Math.floor((1 - value) * 1250) * 0.325);
|
||||
}
|
||||
});
|
||||
|
||||
this.scene.time.delayedCall(4000, () => {
|
||||
this.setCursor(0);
|
||||
this.awaitingActionInput = true;
|
||||
this.onActionInput = args[1];
|
||||
});
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
|
||||
const ui = this.getUi();
|
||||
|
||||
if (!this.awaitingActionInput)
|
||||
return;
|
||||
|
||||
let success = false;
|
||||
|
||||
if (keyCode === keyCodes.Z) {
|
||||
success = true;
|
||||
if (this.onActionInput)
|
||||
this.onActionInput(this.cursor);
|
||||
} else if (keyCode === keyCodes.X) {
|
||||
success = true;
|
||||
if (this.onActionInput)
|
||||
this.onActionInput(-1);
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
case keyCodes.LEFT:
|
||||
if (this.cursor)
|
||||
success = this.setCursor(this.cursor - 1);
|
||||
break;
|
||||
case keyCodes.RIGHT:
|
||||
if (this.cursor < this.options.length - 1)
|
||||
success = this.setCursor(this.cursor + 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ui = this.getUi();
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
|
||||
this.cursorObj.setScale(2);
|
||||
this.modifierContainer.add(this.cursorObj);
|
||||
}
|
||||
|
||||
const sliceWidth = (this.scene.game.canvas.width / 6) / (this.options.length + 2);
|
||||
this.cursorObj.setPosition(sliceWidth * (cursor + 1) + (sliceWidth * 0.5) - 20, -this.scene.game.canvas.height / 12 - 20);
|
||||
ui.showText(this.options[this.cursor].modifierType.description);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
|
||||
this.awaitingActionInput = false;
|
||||
this.onActionInput = null;
|
||||
this.getUi().clearText();
|
||||
this.eraseCursor();
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.overlayBg,
|
||||
alpha: 0,
|
||||
duration: 250,
|
||||
ease: 'Cubic.easeIn'
|
||||
});
|
||||
this.scene.tweens.add({
|
||||
targets: this.options,
|
||||
scale: 0.01,
|
||||
duration: 250,
|
||||
east: 'Elastic.easeIn',
|
||||
onComplete: () => {
|
||||
this.options.forEach(o => o.destroy());
|
||||
this.options.splice(0, this.options.length);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj)
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
|
||||
class ModifierOption extends Phaser.GameObjects.Container {
|
||||
public modifierType: ModifierType;
|
||||
private pb: Phaser.GameObjects.Sprite;
|
||||
private itemContainer: Phaser.GameObjects.Container;
|
||||
private item: Phaser.GameObjects.Sprite;
|
||||
private itemTint: Phaser.GameObjects.Sprite;
|
||||
private itemText: Phaser.GameObjects.Text;
|
||||
|
||||
constructor(scene: BattleScene, x: number, y: number, modifierType: ModifierType) {
|
||||
super(scene, x, y);
|
||||
|
||||
this.modifierType = modifierType;
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
setup() {
|
||||
this.pb = this.scene.add.sprite(0, -150, 'pb', this.getPbAtlasKey());
|
||||
this.pb.setScale(2);
|
||||
this.add(this.pb);
|
||||
|
||||
this.itemContainer = this.scene.add.container(0, 0);
|
||||
this.itemContainer.setScale(0.5);
|
||||
this.itemContainer.setAlpha(0);
|
||||
this.add(this.itemContainer);
|
||||
|
||||
const getItem = () => {
|
||||
const item = this.scene.add.sprite(0, 0, 'items', this.modifierType.iconImage);
|
||||
return item;
|
||||
};
|
||||
|
||||
this.item = getItem();
|
||||
this.itemContainer.add(this.item);
|
||||
|
||||
this.itemTint = getItem();
|
||||
this.itemTint.setTintFill(Phaser.Display.Color.GetColor(255, 192, 255));
|
||||
this.itemContainer.add(this.itemTint);
|
||||
|
||||
this.itemText = addTextObject(this.scene, 0, 35, this.modifierType.name, TextStyle.PARTY, { align: 'center' });
|
||||
this.itemText.setOrigin(0.5, 0);
|
||||
this.itemText.setAlpha(0);
|
||||
this.itemText.setTint(this.getTextTint());
|
||||
this.add(this.itemText);
|
||||
}
|
||||
|
||||
show(remainingDuration: integer) {
|
||||
this.scene.tweens.add({
|
||||
targets: this.pb,
|
||||
y: 0,
|
||||
duration: 1250,
|
||||
ease: 'Bounce.Out'
|
||||
});
|
||||
|
||||
let lastValue = 1;
|
||||
let bounceCount = 0;
|
||||
let bounce = false;
|
||||
|
||||
this.scene.tweens.addCounter({
|
||||
from: 1,
|
||||
to: 0,
|
||||
duration: 1250,
|
||||
ease: 'Bounce.Out',
|
||||
onUpdate: t => {
|
||||
const value = t.getValue();
|
||||
if (!bounce && value > lastValue) {
|
||||
this.scene.sound.play('pb_bounce_1', { volume: 1 / ++bounceCount });
|
||||
bounce = true;
|
||||
} else if (bounce && value < lastValue)
|
||||
bounce = false;
|
||||
lastValue = value;
|
||||
}
|
||||
});
|
||||
|
||||
this.scene.time.delayedCall(remainingDuration + 2000, () => {
|
||||
this.pb.setTexture('pb', `${this.getPbAtlasKey()}_open`);
|
||||
this.scene.sound.play('pb_rel');
|
||||
|
||||
this.scene.tweens.add({
|
||||
targets: this.pb,
|
||||
duration: 500,
|
||||
delay: 250,
|
||||
ease: 'Sine.easeIn',
|
||||
alpha: 0,
|
||||
onComplete: () => this.pb.destroy()
|
||||
})
|
||||
this.scene.tweens.add({
|
||||
targets: this.itemContainer,
|
||||
duration: 500,
|
||||
ease: 'Elastic.Out',
|
||||
scale: 2,
|
||||
alpha: 1
|
||||
});
|
||||
this.scene.tweens.add({
|
||||
targets: this.itemTint,
|
||||
alpha: 0,
|
||||
duration: 500,
|
||||
ease: 'Sine.easeIn',
|
||||
onComplete: () => this.itemTint.destroy()
|
||||
});
|
||||
this.scene.tweens.add({
|
||||
targets: this.itemText,
|
||||
duration: 500,
|
||||
alpha: 1,
|
||||
y: 25,
|
||||
ease: 'Cubic.easeInOut'
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
getPbAtlasKey() {
|
||||
return getPokeballAtlasKey(this.modifierType.tier as unknown as PokeballType);
|
||||
}
|
||||
|
||||
getTextTint(): integer {
|
||||
switch (this.modifierType.tier) {
|
||||
case ModifierTier.COMMON:
|
||||
return 0xffffff
|
||||
case ModifierTier.GREAT:
|
||||
return 0x3890f8;
|
||||
case ModifierTier.ULTRA:
|
||||
return 0xf8d038
|
||||
case ModifierTier.MASTER:
|
||||
return 0xe020c0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,372 @@
|
||||
import { CommandPhase } from "../battle-phase";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { PlayerPokemon } from "../pokemon";
|
||||
import { addTextObject, TextStyle } from "../text";
|
||||
import { Command } from "./command-ui-handler";
|
||||
import MessageUiHandler from "./message-ui-handler";
|
||||
import UI, { Mode } from "./ui";
|
||||
|
||||
const defaultMessage = 'Choose a Pokémon.';
|
||||
|
||||
export default class PartyUiHandler extends MessageUiHandler {
|
||||
private partyContainer: Phaser.GameObjects.Container;
|
||||
private partySlotsContainer: Phaser.GameObjects.Container;
|
||||
private partySlots: PartySlot[];
|
||||
private partyCancelButton: PartyCancelButton;
|
||||
private partyMessageBox: Phaser.GameObjects.Image;
|
||||
|
||||
private lastCursor: integer = 0;
|
||||
private isModal: boolean;
|
||||
private selectCallback: Function;
|
||||
private selectFilter: Function;
|
||||
|
||||
private static FilterAll = (_pokemon: PlayerPokemon) => null;
|
||||
|
||||
public static FilterNonFainted = (pokemon: PlayerPokemon) => {
|
||||
if (!pokemon.hp)
|
||||
return `${pokemon.name} has no energy\nleft to battle!`;
|
||||
return null;
|
||||
};
|
||||
|
||||
public static NoEffectMessage = 'It won\'t have any effect.';
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.PARTY);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
const partyContainer = this.scene.add.container(0, 0);
|
||||
partyContainer.setVisible(false);
|
||||
ui.add(partyContainer);
|
||||
|
||||
this.partyContainer = partyContainer;
|
||||
|
||||
const partyBg = this.scene.add.image(0, 0, 'party_bg');
|
||||
partyContainer.add(partyBg);
|
||||
|
||||
partyBg.setOrigin(0, 1);
|
||||
|
||||
const partySlotsContainer = this.scene.add.container(0, 0);
|
||||
partyContainer.add(partySlotsContainer);
|
||||
|
||||
this.partySlotsContainer = partySlotsContainer;
|
||||
|
||||
const partyMessageBoxContainer = this.scene.add.container(0, -32);
|
||||
partyContainer.add(partyMessageBoxContainer);
|
||||
|
||||
const partyMessageBox = this.scene.add.image(1, 31, 'party_message');
|
||||
partyMessageBox.setOrigin(0, 1);
|
||||
partyMessageBoxContainer.add(partyMessageBox);
|
||||
|
||||
this.partyMessageBox = partyMessageBox;
|
||||
|
||||
const partyMessageText = addTextObject(this.scene, 8, 10, defaultMessage, TextStyle.WINDOW, { maxLines: 2 });
|
||||
partyMessageText.setPositionRelative
|
||||
|
||||
partyMessageText.setOrigin(0, 0);
|
||||
partyMessageBoxContainer.add(partyMessageText);
|
||||
|
||||
this.message = partyMessageText;
|
||||
|
||||
const partyCancelButton = new PartyCancelButton(this.scene, 291, -16);
|
||||
partyContainer.add(partyCancelButton);
|
||||
|
||||
this.partyCancelButton = partyCancelButton;
|
||||
|
||||
this.partySlots = [];
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
super.show(args);
|
||||
|
||||
this.partyContainer.setVisible(true);
|
||||
this.populatePartySlots();
|
||||
this.setCursor(this.cursor < 6 ? this.cursor : 0);
|
||||
|
||||
this.isModal = args.length && args[0];
|
||||
if (args.length > 1 && args[1] instanceof Function)
|
||||
this.selectCallback = args[1];
|
||||
this.selectFilter = args.length > 2 && args[2] instanceof Function
|
||||
? args[2]
|
||||
: PartyUiHandler.FilterAll;
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
const ui = this.getUi();
|
||||
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
|
||||
|
||||
if (this.pendingPrompt)
|
||||
return;
|
||||
|
||||
if (this.awaitingActionInput) {
|
||||
if (keyCode === keyCodes.Z || keyCode === keyCodes.X) {
|
||||
if (this.onActionInput) {
|
||||
ui.playSelect();
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
this.awaitingActionInput = false;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (keyCode === keyCodes.Z) {
|
||||
if (this.cursor < 6) {
|
||||
let filterResult: string = this.selectFilter(this.scene.getParty()[this.cursor]);
|
||||
if (filterResult === null) {
|
||||
if (this.selectCallback) {
|
||||
const selectCallback = this.selectCallback;
|
||||
this.selectCallback = null;
|
||||
selectCallback(this.cursor);
|
||||
return;
|
||||
} else if (this.cursor)
|
||||
(this.scene.getCurrentPhase() as CommandPhase).handleCommand(Command.POKEMON, this.cursor);
|
||||
else
|
||||
this.processInput(keyCodes.X);
|
||||
} else {
|
||||
this.partyMessageBox.setTexture('party_message_large');
|
||||
this.message.y -= 15;
|
||||
this.showText(filterResult as string, null, () => {
|
||||
this.partyMessageBox.setTexture('party_message');
|
||||
this.message.text = defaultMessage;
|
||||
this.message.y += 15;
|
||||
}, null, true);
|
||||
}
|
||||
} else if (this.isModal)
|
||||
ui.playError();
|
||||
else
|
||||
this.processInput(keyCodes.X);
|
||||
return;
|
||||
} else if (keyCode === keyCodes.X) {
|
||||
if (!this.isModal) {
|
||||
if (this.selectCallback) {
|
||||
const selectCallback = this.selectCallback;
|
||||
this.selectCallback = null;
|
||||
selectCallback(6);
|
||||
ui.playSelect();
|
||||
} else {
|
||||
ui.setMode(Mode.COMMAND);
|
||||
ui.playSelect();
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const slotCount = this.partySlots.length;
|
||||
let success = false;
|
||||
|
||||
switch (keyCode) {
|
||||
case keyCodes.UP:
|
||||
success = this.setCursor(this.cursor ? this.cursor < 6 ? this.cursor - 1 : slotCount - 1 : 6);
|
||||
break;
|
||||
case keyCodes.DOWN:
|
||||
success = this.setCursor(this.cursor < 6 ? this.cursor < slotCount - 1 ? this.cursor + 1 : 6 : 0);
|
||||
break;
|
||||
case keyCodes.LEFT:
|
||||
if (this.cursor && this.cursor < 6)
|
||||
success = this.setCursor(0);
|
||||
break;
|
||||
case keyCodes.RIGHT:
|
||||
if (!this.cursor)
|
||||
success = this.setCursor(this.lastCursor < 6 ? this.lastCursor || 1 : 1);
|
||||
break;
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const changed = this.cursor !== cursor;
|
||||
if (changed) {
|
||||
this.lastCursor = this.cursor;
|
||||
this.cursor = cursor;
|
||||
if (this.lastCursor < 6)
|
||||
this.partySlots[this.lastCursor].deselect();
|
||||
else if (this.lastCursor === 6)
|
||||
this.partyCancelButton.deselect();
|
||||
if (cursor < 6)
|
||||
this.partySlots[cursor].select();
|
||||
else if (cursor === 6)
|
||||
this.partyCancelButton.select();
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
populatePartySlots() {
|
||||
const party = (this.scene as BattleScene).getParty();
|
||||
|
||||
if (this.cursor < 6 && this.cursor >= party.length)
|
||||
this.cursor = party.length - 1;
|
||||
else if (this.cursor === 6)
|
||||
this.partyCancelButton.select();
|
||||
|
||||
for (let p in party) {
|
||||
const slotIndex = parseInt(p);
|
||||
const partySlot = new PartySlot(this.scene as BattleScene, slotIndex, party[p]);
|
||||
this.scene.add.existing(partySlot);
|
||||
this.partySlotsContainer.add(partySlot);
|
||||
this.partySlots.push(partySlot);
|
||||
if (this.cursor === slotIndex)
|
||||
partySlot.select();
|
||||
}
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.partyContainer.setVisible(false);
|
||||
this.clearPartySlots();
|
||||
}
|
||||
|
||||
clearPartySlots() {
|
||||
this.partySlots.splice(0, this.partySlots.length);
|
||||
this.partySlotsContainer.removeAll(true);
|
||||
}
|
||||
}
|
||||
|
||||
class PartySlot extends Phaser.GameObjects.Container {
|
||||
private selected: boolean;
|
||||
private slotIndex: integer;
|
||||
private pokemon: PlayerPokemon;
|
||||
|
||||
private slotBg: Phaser.GameObjects.Image;
|
||||
private slotPb: Phaser.GameObjects.Sprite;
|
||||
private slotPokemonIcon: Phaser.GameObjects.Sprite;
|
||||
private slotHpOverlay: Phaser.GameObjects.Sprite;
|
||||
|
||||
constructor(scene: BattleScene, slotIndex: integer, pokemon: PlayerPokemon) {
|
||||
super(scene, slotIndex ? 230.5 : 64, slotIndex ? -184 + 28 * slotIndex : -124);
|
||||
|
||||
this.slotIndex = slotIndex;
|
||||
this.pokemon = pokemon;
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
setup() {
|
||||
const slotKey = `party_slot${this.slotIndex ? '' : '_main'}`;
|
||||
|
||||
const slotBg = this.scene.add.sprite(0, 0, slotKey, `${slotKey}${this.pokemon.hp ? '' : '_fnt'}`);
|
||||
this.slotBg = slotBg;
|
||||
|
||||
this.add(slotBg);
|
||||
|
||||
const slotPb = this.scene.add.sprite(this.slotIndex ? -85.5 : -51, this.slotIndex ? 0 : -20.5, 'party_pb');
|
||||
this.slotPb = slotPb;
|
||||
|
||||
this.add(slotPb);
|
||||
|
||||
const pokemonIcon = this.scene.add.sprite(slotPb.x, slotPb.y, this.pokemon.getIconAtlasKey());
|
||||
console.log(pokemonIcon)
|
||||
pokemonIcon.play(this.pokemon.getIconKey());
|
||||
this.slotPokemonIcon = pokemonIcon;
|
||||
|
||||
this.add(pokemonIcon);
|
||||
|
||||
const slotInfoContainer = this.scene.add.container(0, 0);
|
||||
this.add(slotInfoContainer);
|
||||
|
||||
const slotName = addTextObject(this.scene, 0, 0, this.pokemon.name, TextStyle.PARTY);
|
||||
slotName.setPositionRelative(slotBg, this.slotIndex ? 21 : 24, this.slotIndex ? 3 : 10);
|
||||
slotName.setOrigin(0, 0);
|
||||
|
||||
const slotLevelLabel = this.scene.add.image(0, 0, 'party_slot_overlay_lv');
|
||||
slotLevelLabel.setPositionRelative(slotName, 8, 12);
|
||||
slotLevelLabel.setOrigin(0, 0);
|
||||
|
||||
const slotLevelText = addTextObject(this.scene, 0, 0, this.pokemon.level.toString(), TextStyle.PARTY);
|
||||
slotLevelText.setPositionRelative(slotLevelLabel, 9, 0);
|
||||
slotLevelText.setOrigin(0, 0.25);
|
||||
|
||||
const slotHpBar = this.scene.add.image(0, 0, 'party_slot_hp_bar');
|
||||
slotHpBar.setPositionRelative(slotBg, this.slotIndex ? 72 : 8, this.slotIndex ? 7 : 31);
|
||||
slotHpBar.setOrigin(0, 0);
|
||||
|
||||
const hpRatio = this.pokemon.hp / this.pokemon.getMaxHp();
|
||||
|
||||
const slotHpOverlay = this.scene.add.sprite(0, 0, 'party_slot_hp_overlay', hpRatio > 0.5 ? 'high' : hpRatio > 0.25 ? 'medium' : 'low');
|
||||
slotHpOverlay.setPositionRelative(slotHpBar, 16, 2);
|
||||
slotHpOverlay.setOrigin(0, 0);
|
||||
slotHpOverlay.setScale(hpRatio, 1);
|
||||
|
||||
const slotHpText = addTextObject(this.scene, 0, 0, `${this.pokemon.hp}/${this.pokemon.getMaxHp()}`, TextStyle.PARTY);
|
||||
slotHpText.setPositionRelative(slotHpBar, slotHpBar.width - 3, slotHpBar.height - 2);
|
||||
slotHpText.setOrigin(1, 0);
|
||||
|
||||
slotInfoContainer.add([ slotName, slotLevelLabel, slotLevelText, slotHpBar, slotHpOverlay, slotHpText ]);
|
||||
|
||||
this.slotHpOverlay = slotHpOverlay;
|
||||
}
|
||||
|
||||
select() {
|
||||
if (this.selected)
|
||||
return;
|
||||
|
||||
this.selected = true;
|
||||
|
||||
this.slotBg.setTexture(`party_slot${this.slotIndex ? '' : '_main'}`, `party_slot${this.slotIndex ? '' : '_main'}${this.pokemon.hp ? '' : '_fnt'}_sel`);
|
||||
this.slotPb.setFrame('party_pb_sel');
|
||||
}
|
||||
|
||||
deselect() {
|
||||
if (!this.selected)
|
||||
return;
|
||||
|
||||
this.selected = false;
|
||||
|
||||
this.slotBg.setTexture(`party_slot${this.slotIndex ? '' : '_main'}`, `party_slot${this.slotIndex ? '' : '_main'}${this.pokemon.hp ? '' : '_fnt'}`);
|
||||
this.slotPb.setFrame('party_pb');
|
||||
}
|
||||
}
|
||||
|
||||
class PartyCancelButton extends Phaser.GameObjects.Container {
|
||||
private selected: boolean;
|
||||
|
||||
private partyCancelBg: Phaser.GameObjects.Sprite;
|
||||
private partyCancelPb: Phaser.GameObjects.Sprite;
|
||||
|
||||
constructor(scene: BattleScene, x: number, y: number) {
|
||||
super(scene, x, y);
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
setup() {
|
||||
const partyCancelBg = this.scene.add.sprite(0, 0, 'party_cancel');
|
||||
this.add(partyCancelBg);
|
||||
|
||||
this.partyCancelBg = partyCancelBg;
|
||||
|
||||
const partyCancelPb = this.scene.add.sprite(-17, 0, 'party_pb');
|
||||
this.add(partyCancelPb);
|
||||
|
||||
this.partyCancelPb = partyCancelPb;
|
||||
|
||||
const partyCancelText = addTextObject(this.scene, -7, -6, 'CANCEL', TextStyle.PARTY);
|
||||
this.add(partyCancelText);
|
||||
}
|
||||
|
||||
select() {
|
||||
if (this.selected)
|
||||
return;
|
||||
|
||||
this.selected = true;
|
||||
|
||||
this.partyCancelBg.setFrame(`party_cancel_sel`);
|
||||
this.partyCancelPb.setFrame('party_pb_sel');
|
||||
}
|
||||
|
||||
deselect() {
|
||||
if (!this.selected)
|
||||
return;
|
||||
|
||||
this.selected = false;
|
||||
|
||||
this.partyCancelBg.setFrame('party_cancel');
|
||||
this.partyCancelPb.setFrame('party_pb');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
import { SwitchPhase, SwitchSummonPhase } from "../battle-phase";
|
||||
import BattleScene from "../battle-scene";
|
||||
import { addTextObject, TextStyle } from "../text";
|
||||
import AwaitableUiHandler from "./awaitable-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
|
||||
export default class SwitchCheckUiHandler extends AwaitableUiHandler {
|
||||
private switchCheckContainer: Phaser.GameObjects.Container;
|
||||
private switchCheckBg: Phaser.GameObjects.Image;
|
||||
|
||||
private cursorObj: Phaser.GameObjects.Image;
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, Mode.SWITCH_CHECK);
|
||||
}
|
||||
|
||||
setup() {
|
||||
const ui = this.getUi();
|
||||
|
||||
const switchCheckContainer = this.scene.add.container((this.scene.game.canvas.width / 6) - 49, -49);
|
||||
switchCheckContainer.setVisible(false);
|
||||
ui.add(switchCheckContainer);
|
||||
|
||||
this.switchCheckContainer = switchCheckContainer;
|
||||
|
||||
const switchCheckBg = this.scene.add.image(0, 0, 'boolean_window');
|
||||
switchCheckBg.setOrigin(0, 1);
|
||||
switchCheckContainer.add(switchCheckBg);
|
||||
|
||||
this.switchCheckBg = switchCheckBg;
|
||||
|
||||
const switchCheckText = addTextObject(this.scene, 0, 0, 'Yes\nNo', TextStyle.WINDOW, { maxLines: 2 });
|
||||
switchCheckText.setPositionRelative(switchCheckBg, 16, 9);
|
||||
switchCheckText.setLineSpacing(12);
|
||||
switchCheckContainer.add(switchCheckText);
|
||||
|
||||
this.setCursor(0)
|
||||
}
|
||||
|
||||
show(args: any[]) {
|
||||
if (args.length && args[0] instanceof Function) {
|
||||
super.show(args);
|
||||
|
||||
this.awaitingActionInput = true;
|
||||
this.onActionInput = args[0] as Function;
|
||||
|
||||
this.switchCheckContainer.setVisible(true);
|
||||
this.setCursor(this.cursor);
|
||||
}
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
const keyCodes = Phaser.Input.Keyboard.KeyCodes;
|
||||
const ui = this.getUi();
|
||||
|
||||
if (!this.awaitingActionInput)
|
||||
return;
|
||||
|
||||
let success = false;
|
||||
|
||||
if (keyCode === keyCodes.Z || keyCode === keyCodes.X) {
|
||||
success = true;
|
||||
if (keyCode === keyCodes.X)
|
||||
this.cursor = 1;
|
||||
if (this.onActionInput) {
|
||||
if (!this.cursor)
|
||||
this.scene.unshiftPhase(new SwitchPhase(this.scene, false, true));
|
||||
const originalOnActionInput = this.onActionInput;
|
||||
this.onActionInput = null;
|
||||
originalOnActionInput();
|
||||
this.clear();
|
||||
}
|
||||
} else {
|
||||
switch (keyCode) {
|
||||
case keyCodes.UP:
|
||||
if (this.cursor)
|
||||
success = this.setCursor(0);
|
||||
break;
|
||||
case keyCodes.DOWN:
|
||||
if (!this.cursor)
|
||||
success = this.setCursor(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (success)
|
||||
ui.playSelect();
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const ui = this.getUi();
|
||||
const ret = super.setCursor(cursor);
|
||||
|
||||
if (!this.cursorObj) {
|
||||
this.cursorObj = this.scene.add.image(0, 0, 'cursor');
|
||||
this.switchCheckContainer.add(this.cursorObj);
|
||||
}
|
||||
|
||||
this.cursorObj.setPositionRelative(this.switchCheckBg, 12, this.cursor ? 33 : 17);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
clear() {
|
||||
super.clear();
|
||||
this.switchCheckContainer.setVisible(false);
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
eraseCursor() {
|
||||
if (this.cursorObj)
|
||||
this.cursorObj.destroy();
|
||||
this.cursorObj = null;
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
import { default as BattleScene } from '../battle-scene';
|
||||
import UiHandler from './uiHandler';
|
||||
import BattleMessageUiHandler from './battle-message-ui-handler';
|
||||
import CommandUiHandler from './command-ui-handler';
|
||||
import PartyUiHandler from './party-ui-handler';
|
||||
import FightUiHandler from './fight-ui-handler';
|
||||
import MessageUiHandler from './message-ui-handler';
|
||||
import SwitchCheckUiHandler from './switch-check-ui-handler';
|
||||
import ModifierSelectUiHandler from './modifier-select-ui-handler';
|
||||
|
||||
export enum Mode {
|
||||
MESSAGE = 0,
|
||||
COMMAND,
|
||||
FIGHT,
|
||||
SWITCH_CHECK,
|
||||
MODIFIER_SELECT,
|
||||
PARTY
|
||||
};
|
||||
|
||||
export default class UI extends Phaser.GameObjects.Container {
|
||||
private mode: Mode;
|
||||
private handlers: UiHandler[];
|
||||
|
||||
constructor(scene: BattleScene) {
|
||||
super(scene, 0, scene.game.canvas.height / 6);
|
||||
|
||||
this.mode = Mode.MESSAGE;
|
||||
this.handlers = [
|
||||
new BattleMessageUiHandler(scene),
|
||||
new CommandUiHandler(scene),
|
||||
new FightUiHandler(scene),
|
||||
new SwitchCheckUiHandler(scene),
|
||||
new ModifierSelectUiHandler(scene),
|
||||
new PartyUiHandler(scene)
|
||||
];
|
||||
}
|
||||
|
||||
setup() {
|
||||
for (let handler of this.handlers) {
|
||||
handler.setup();
|
||||
}
|
||||
}
|
||||
|
||||
getHandler() {
|
||||
return this.handlers[this.mode];
|
||||
}
|
||||
|
||||
getMessageHandler() {
|
||||
return this.handlers[Mode.MESSAGE] as BattleMessageUiHandler;
|
||||
}
|
||||
|
||||
processInput(keyCode: integer) {
|
||||
this.getHandler().processInput(keyCode);
|
||||
}
|
||||
|
||||
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean) {
|
||||
const handler = this.getHandler();
|
||||
if (handler instanceof MessageUiHandler)
|
||||
(handler as MessageUiHandler).showText(text, delay, callback, callbackDelay, prompt);
|
||||
else
|
||||
this.getMessageHandler().showText(text, delay, callback, callbackDelay, prompt);
|
||||
}
|
||||
|
||||
clearText() {
|
||||
const handler = this.getHandler();
|
||||
if (handler instanceof MessageUiHandler)
|
||||
(handler as MessageUiHandler).clearText();
|
||||
else
|
||||
this.getMessageHandler().clearText();
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const changed = this.getHandler().setCursor(cursor);
|
||||
if (changed)
|
||||
this.playSelect();
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
playSelect() {
|
||||
this.scene.sound.play('select');
|
||||
}
|
||||
|
||||
playError() {
|
||||
this.scene.sound.play('error');
|
||||
}
|
||||
|
||||
setMode(mode: Mode, ...args: any[]) {
|
||||
if (this.mode === mode)
|
||||
return;
|
||||
this.getHandler().clear();
|
||||
this.mode = mode;
|
||||
this.getHandler().show(args);
|
||||
}
|
||||
|
||||
setModeWithoutClear(mode: Mode, ...args: any[]) {
|
||||
if (this.mode === mode)
|
||||
return;
|
||||
this.mode = mode;
|
||||
this.getHandler().show(args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import BattleScene from "../battle-scene";
|
||||
import UI, { Mode } from "./ui";
|
||||
|
||||
export default abstract class UiHandler {
|
||||
protected scene: BattleScene;
|
||||
protected mode: integer;
|
||||
protected cursor: integer = 0;
|
||||
protected active: boolean = false;
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode) {
|
||||
this.scene = scene;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
abstract setup(): void;
|
||||
|
||||
show(_args: any[]): void {
|
||||
this.active = true;
|
||||
}
|
||||
|
||||
abstract processInput(keyCode: integer);
|
||||
|
||||
getUi() {
|
||||
return this.scene.ui;
|
||||
}
|
||||
|
||||
setCursor(cursor: integer): boolean {
|
||||
const changed = this.cursor !== cursor;
|
||||
if (changed)
|
||||
this.cursor = cursor;
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
clear() {
|
||||
this.active = false;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user