From 4a354cd7a4edb203dd5e66355dbed0e62994e09b Mon Sep 17 00:00:00 2001 From: Mike Vink Date: Thu, 29 Jul 2021 03:34:50 +0200 Subject: feat(): handshaker part1 --- client/src/akkamon/client/Client.ts | 10 ++++-- client/src/akkamon/client/InteractionEngine.ts | 43 +++++++++++++++++++++-- client/src/akkamon/scenes/DemoScene.ts | 12 ++++++- client/src/akkamon/scenes/UIElement.ts | 47 ++++++++++++++++++++++---- client/src/akkamon/scenes/WorldScene.ts | 22 ++++++------ 5 files changed, 110 insertions(+), 24 deletions(-) (limited to 'client') diff --git a/client/src/akkamon/client/Client.ts b/client/src/akkamon/client/Client.ts index 2cc5ee8..1591347 100644 --- a/client/src/akkamon/client/Client.ts +++ b/client/src/akkamon/client/Client.ts @@ -32,6 +32,7 @@ import { import type { IncomingEvent, + IncomingInteractionRequest } from './IncomingEvents'; import { @@ -91,7 +92,7 @@ export class Client implements AkkamonClient case EventType.INTERACTION_REQUEST: console.log("Received an interaction request!"); console.log(event); - // this.interactionEngine!.push(event); + this.interactionEngine!.push(event as IncomingInteractionRequest); break; default: console.log("ignored incoming event, doesn't match EventType interface."); @@ -116,6 +117,7 @@ export class Client implements AkkamonClient } setUIControls(input: Phaser.Input.InputPlugin, menu: any) { + console.log("setting ui controls!"); this.controls = new UIControls(input, menu); } @@ -201,10 +203,12 @@ export class Client implements AkkamonClient } sendInteractionRequest(interaction: Interaction) { - console.log("sent a battle request!"); + console.log("sent an interaction request!"); console.log(this.getCurrentSceneKey()); console.log(JSON.stringify(interaction)); - this.interactionEngine!.setAwaitingResponse(); + + this.interactionEngine!.setAwaitingInteractionRequestInitiation(true); + this.send(new OutgoingInteractionRequestEvent( this.getCurrentSceneKey(), interaction diff --git a/client/src/akkamon/client/InteractionEngine.ts b/client/src/akkamon/client/InteractionEngine.ts index 92b6b81..cf0c947 100644 --- a/client/src/akkamon/client/InteractionEngine.ts +++ b/client/src/akkamon/client/InteractionEngine.ts @@ -4,6 +4,11 @@ import type { WorldScene } from '../scenes/WorldScene'; import { baseQueue } from '../DataWrappers'; +import { + InteractionRequestDialogue, + WaitingDialogue +} from '../scenes/UIElement'; + import type { IncomingInteractionRequest } from './IncomingEvents'; @@ -11,18 +16,52 @@ import type { export class InteractionEngine extends AkkamonEngine { + private scene: WorldScene; + private messageQueue = baseQueue(); + private awaitingInit: boolean = false; + + private waitingForResponseOf: String | undefined; + + private requestBackLog = baseQueue(); + + private answering: boolean = false; + constructor(scene: WorldScene) { super(); + this.scene = scene; + } + + playerIsBusy() { + return this.waitingForResponseOf || this.awaitingInit || this.answering } update() { + if (!this.requestBackLog.isEmpty() + && !this.playerIsBusy() + && this.scene.menus.isEmpty()) { + let message = this.requestBackLog.pop(); + this.scene.pushMenu(new InteractionRequestDialogue(this.scene, ["YES", "NO"], {name: message!.trainerId, requestType: message!.type})); + } } - setAwaitingResponse() { + setAwaitingInteractionRequestInitiation(value: boolean) { + this.awaitingInit = value; } - push() { + push(event: IncomingInteractionRequest) { + // check trainerId + if (this.awaitingInit) { + this.waitingForResponseOf = event.requestName; + this.scene.clearMenus(); + + this.scene.pushMenu(new WaitingDialogue(this.scene, new Phaser.GameObjects.Group(this.scene), 20, 'Awaiting player response...')); + + this.awaitingInit = false; + } else { + this.requestBackLog.push(event); + } } + } diff --git a/client/src/akkamon/scenes/DemoScene.ts b/client/src/akkamon/scenes/DemoScene.ts index 9544df3..b6b94e5 100644 --- a/client/src/akkamon/scenes/DemoScene.ts +++ b/client/src/akkamon/scenes/DemoScene.ts @@ -1,5 +1,7 @@ import Phaser from 'phaser'; +import { client } from '../../app'; + import type { BasePhaserScene } from '../PhaserTypes'; @@ -9,6 +11,14 @@ import { createWorldScene } from './WorldScene'; -let DemoScene = createWorldScene(Phaser.Scene, "DemoScene", "map", "akkamon-demo-extruded"); +function updatable(scene: Scene) { + return class DemoScene extends scene { + update(time: number, delta: number) { + client.updateScene(delta); + } + } +} + +let DemoScene = updatable(createWorldScene(Phaser.Scene, "DemoScene", "map", "akkamon-demo-extruded")); export default DemoScene; diff --git a/client/src/akkamon/scenes/UIElement.ts b/client/src/akkamon/scenes/UIElement.ts index 03cce88..f1d5dd3 100644 --- a/client/src/akkamon/scenes/UIElement.ts +++ b/client/src/akkamon/scenes/UIElement.ts @@ -24,7 +24,9 @@ class MenuText extends Phaser.GameObjects.Text { scene.add.existing(this); group.add(this); this.setDepth(groupDepth); + } + } class WrappedMenuText extends MenuText { @@ -67,6 +69,7 @@ export interface AkkamonMenu { destroyAndGoBack: () => void confirm: () => void destroyGroup: () => void + setMenuVisible: (v: boolean) => void } @@ -91,6 +94,10 @@ class Menu extends Phaser.GameObjects.Image implements AkkamonMenu { xOffsetFromRight?: number pickerOffset?:number + setMenuVisible(value: boolean) { + this.group!.setVisible(value); + } + destroyGroup() { this.group!.destroy(true); } @@ -297,7 +304,7 @@ class ConfirmationDialogue extends Menu implements AkkamonMenu { options?: Array dialogueBox?: Dialogue - constructor(scene: WorldScene, options: Array, dialogueData: {[key: string]: string}) { + constructor(scene: WorldScene, options: Array, dialogueData: {[key: string]: string} | string) { super(scene, "confirmation-dialogue"); let camera = scene.cameras.main; this.setDisplaySize(200, 0.83 * 200) @@ -347,6 +354,10 @@ class Dialogue extends Phaser.GameObjects.Image implements AkkamonMenu { ); } + setMenuVisible(value: boolean) { + this.group!.setVisible(value); + } + selectButton() { } confirm() { @@ -416,7 +427,7 @@ class ChallengeDialogue extends ConfirmationDialogue implements AkkamonMenu { if (this.buttons![this.index!].text === "YES") { this.akkamonScene.requestBattle(this.challengedTrainerName); this.akkamonScene.clearMenus(); - this.akkamonScene.pushMenu(new WaitingDialogue(this.akkamonScene, new Phaser.GameObjects.Group(this.scene), 20)); + this.akkamonScene.pushMenu(new WaitingDialogue(this.akkamonScene, new Phaser.GameObjects.Group(this.scene), 20, 'Awaiting request initialisation...')); } else { this.destroyAndGoBack(); } @@ -428,14 +439,37 @@ class ChallengeDialogue extends ConfirmationDialogue implements AkkamonMenu { } } -class WaitingDialogue extends Dialogue { +export class InteractionRequestDialogue extends ConfirmationDialogue implements AkkamonMenu { + + constructor(scene: WorldScene, options: Array, dialogueData: {name: string, requestType: string}) { + super(scene, options, dialogueData); + this.dialogueBox!.push( + `Do you want to ${dialogueData.requestType} with ${dialogueData.name}?` + ); + this.dialogueBox!.displayNextDialogue(); + } + + confirm() { + if (this.buttons![this.index!].text === "YES") { + } else { + this.destroyAndGoBack(); + } + } + + destroy() { + this.scene.time.removeAllEvents(); + super.destroy(); + } +} + +export class WaitingDialogue extends Dialogue { waitingPrinter: any - constructor(scene: WorldScene, group: Phaser.GameObjects.Group, depth: number) { + constructor(scene: WorldScene, group: Phaser.GameObjects.Group, depth: number, text: string) { super(scene, group, depth); - this.typewriteText("Waiting on reponse..."); + this.typewriteText(text); this.waitingPrinter = setInterval(() => { this.displayedText.text = ''; - this.typewriteText("Waiting on reponse..."); + this.typewriteText(text); }, 3000); } @@ -449,4 +483,5 @@ class WaitingDialogue extends Dialogue { this.scene.time.removeAllEvents(); super.destroy(); } + } diff --git a/client/src/akkamon/scenes/WorldScene.ts b/client/src/akkamon/scenes/WorldScene.ts index fd866aa..3e8db40 100644 --- a/client/src/akkamon/scenes/WorldScene.ts +++ b/client/src/akkamon/scenes/WorldScene.ts @@ -17,8 +17,6 @@ export let TILE_SIZE = 32; export interface WorldScene extends Phaser.Scene { - client: typeof client; - map?: Phaser.Tilemaps.Tilemap spawnPoint?: Phaser.Types.Tilemaps.TiledObject; spawnPointTilePos?: { @@ -47,15 +45,14 @@ export interface WorldScene extends Phaser.Scene { requestBattle: (remotePlayerData: string | string[]) => void clearMenus: () => void + } export function createWorldScene(scene: PhaserScene, sceneKey: string, mapKey: string, tileSetKey: string) { - return class WorldScene extends scene implements WorldScene { + return class WorldScene extends scene { map?: Phaser.Tilemaps.Tilemap; - client = client; - menus = baseStack(); spawnPoint?: Phaser.Types.Tilemaps.TiledObject; @@ -90,7 +87,7 @@ export function createWorldScene(scene: Pha ); this.spawnPointTilePos = tilePos; - this.client.requestInitWorldScene( + client.requestInitWorldScene( this ); @@ -104,11 +101,11 @@ export function createWorldScene(scene: Pha } menuTakesUIControl(input: Phaser.Input.InputPlugin, menu: AkkamonMenu): void { - this.client.setUIControls(input, menu); + client.setUIControls(input, menu); } isUsingGridControls() { - this.client.setGridControls(); + client.setGridControls(); } pushMenu(menu: AkkamonMenu) { @@ -126,6 +123,7 @@ export function createWorldScene(scene: Pha this.popMenu(); if (!this.menus.isEmpty()) { this.menuTakesUIControl(this.input, this.menus.peek()!); + this.menus.peek()!.setMenuVisible(true); } else { this.isUsingGridControls(); } @@ -134,11 +132,11 @@ export function createWorldScene(scene: Pha } getPlayerPixelPosition(): Phaser.Math.Vector2 { - return this.client.requestPlayerPixelPosition(); + return client.requestPlayerPixelPosition(); } getRemotePlayerNames(): Array { - let remotePlayerData = this.client.requestRemotePlayerData(); + let remotePlayerData = client.requestRemotePlayerData(); if (remotePlayerData.size === 0) { return ['Nobody Online']; } else { @@ -147,9 +145,9 @@ export function createWorldScene(scene: Pha } requestBattle(remotePlayerName: string | string[]): void { - this.client.sendInteractionRequest({ + client.sendInteractionRequest({ type: "battle", - requestingTrainerId: this.client.getSessionTrainerId()!, + requestingTrainerId: client.getSessionTrainerId()!, receivingTrainerIds: Array.isArray(remotePlayerName) ? remotePlayerName : [remotePlayerName] }); } -- cgit v1.2.3