diff options
| author | Mike Vink <mike1994vink@gmail.com> | 2021-07-25 13:32:25 +0200 |
|---|---|---|
| committer | Mike Vink <mike1994vink@gmail.com> | 2021-07-25 13:32:25 +0200 |
| commit | 2c017b243238c9f9559fc645882e6e8a06328390 (patch) | |
| tree | 55dccf803580d0ede61575eec0b8da3249ae2b52 | |
| parent | 4692175208a8f0526c6e0881aa0e51345c5574fb (diff) | |
feat(PauseMenu): first version
| -rw-r--r-- | client/src/akkamon/GameConfig.ts | 5 | ||||
| -rw-r--r-- | client/src/akkamon/client/Client.ts | 19 | ||||
| -rw-r--r-- | client/src/akkamon/render/UIControls.ts | 23 | ||||
| -rw-r--r-- | client/src/akkamon/scenes/AkkamonWorldScene.ts | 48 | ||||
| -rw-r--r-- | client/src/akkamon/scenes/BootScene.ts | 3 | ||||
| -rw-r--r-- | client/src/akkamon/scenes/DemoScene.ts | 33 | ||||
| -rw-r--r-- | client/src/akkamon/scenes/UIElement.ts | 142 | ||||
| -rw-r--r-- | client/src/akkamon/scenes/UIScene.ts | 122 |
8 files changed, 230 insertions, 165 deletions
diff --git a/client/src/akkamon/GameConfig.ts b/client/src/akkamon/GameConfig.ts index 11fc26a..8d7e4f1 100644 --- a/client/src/akkamon/GameConfig.ts +++ b/client/src/akkamon/GameConfig.ts @@ -1,7 +1,4 @@ import { - UIScene -} from './scenes/UIScene'; -import { DemoScene } from './scenes/DemoScene'; import { @@ -15,5 +12,5 @@ export const gameConfig: Phaser.Types.Core.GameConfig & Phaser.Types.Core.Render width: 800, height: 600, pixelArt: true, - scene: [BootScene, DemoScene, UIScene] + scene: [BootScene, DemoScene] }; diff --git a/client/src/akkamon/client/Client.ts b/client/src/akkamon/client/Client.ts index b0caa98..a48bc0e 100644 --- a/client/src/akkamon/client/Client.ts +++ b/client/src/akkamon/client/Client.ts @@ -3,7 +3,10 @@ import { Socket } from './Socket'; import { PlayerSprite } from '../render/model/PlayerSprite'; import { GridPhysics } from '../render/engine/GridPhysics'; + import { GridControls } from '../render/GridControls'; +import { UIControls } from '../render/UIControls'; + import { RemotePlayerEngine } from '../render/engine/RemotePlayerEngine'; @@ -29,7 +32,7 @@ export class Client implements AkkamonClient private scene?: AkkamonWorldScene; private gridPhysics?: GridPhysics; - private gridControls?: GridControls; + private controls?: GridControls | UIControls; private remotePlayerEngine?: RemotePlayerEngine; @@ -64,11 +67,21 @@ export class Client implements AkkamonClient } updateScene(delta: number): void { - this.gridControls!.update(); + this.controls!.update(); this.gridPhysics!.update(delta); this.remotePlayerEngine!.update(delta); } + setUIControls() { + this.controls = new UIControls(this.scene!.input, this.scene!.activeMenu!); + } + + async setGridControls() { + function delay(ms: number) { return new Promise( resolve => setTimeout(resolve, ms) ); } + await delay(100); + this.controls = new GridControls(this.scene!.input, this.gridPhysics!); + } + requestInitPlayerSprite( scene: AkkamonWorldScene ): void { @@ -87,7 +100,7 @@ export class Client implements AkkamonClient scene.map! ); - this.gridControls = new GridControls( + this.controls = new GridControls( scene.input, this.gridPhysics ); diff --git a/client/src/akkamon/render/UIControls.ts b/client/src/akkamon/render/UIControls.ts index d402cf3..89eba32 100644 --- a/client/src/akkamon/render/UIControls.ts +++ b/client/src/akkamon/render/UIControls.ts @@ -1,2 +1,25 @@ +import { Direction } from '../render/Direction'; +import type { AkkamonMenu } from '../scenes/UIElement'; + export class UIControls { + private cursors: Phaser.Types.Input.Keyboard.CursorKeys; + + constructor( + private input: Phaser.Input.InputPlugin, + private menu: AkkamonMenu, + ) { + this.cursors = this.input.keyboard.createCursorKeys(); + } + + update() { + if (Phaser.Input.Keyboard.JustDown(this.cursors.left)) { + this.menu.destroyMe(); + } else if (Phaser.Input.Keyboard.JustDown(this.cursors.right)) { + this.menu.confirm(); + } else if (Phaser.Input.Keyboard.JustDown(this.cursors.up)) { + this.menu.selectButton(Direction.UP); + } else if (Phaser.Input.Keyboard.JustDown(this.cursors.down)) { + this.menu.selectButton(Direction.DOWN); + } + } } diff --git a/client/src/akkamon/scenes/AkkamonWorldScene.ts b/client/src/akkamon/scenes/AkkamonWorldScene.ts index b9cfc20..1b4d67a 100644 --- a/client/src/akkamon/scenes/AkkamonWorldScene.ts +++ b/client/src/akkamon/scenes/AkkamonWorldScene.ts @@ -2,8 +2,11 @@ import Phaser from 'phaser'; import { client } from '../../app'; +import { PauseMenu, AkkamonMenu } from '../scenes/UIElement'; + export let eventsCenter = new Phaser.Events.EventEmitter(); + export class AkkamonWorldScene extends Phaser.Scene { static readonly TILE_SIZE = 32; @@ -20,4 +23,49 @@ export class AkkamonWorldScene extends Phaser.Scene { spawnPoint: Phaser.Types.Tilemaps.TiledObject | undefined; + pauseMenu?: PauseMenu; + + activeMenu?: AkkamonMenu; + + create(mapKey: string, tileSetKey: string) { + this.map = this.make.tilemap({ key: mapKey }); + // Parameters are the name you gave the tileset in Tiled and then the key of the tileset image in + // Phaser's cache (i.e. the name you used in preload) + const tileset = this.map.addTilesetImage(tileSetKey, "tiles"); + // Parameters: layer name (or index) from Tiled, tileset, x, y + const belowLayer = this.map.createLayer("Below Player", tileset, 0, 0); + const worldLayer = this.map.createLayer("World", tileset, 0, 0); + const aboveLayer = this.map.createLayer("Above Player", tileset, 0, 0); + // By default, everything gets depth sorted on the screen in the order we created things. Here, we + // want the "Above Player" layer to sit on top of the player, so we explicitly give it a depth. + // Higher depths will sit on top of lower depth objects. + aboveLayer.setDepth(10); + + this.spawnPoint = this.map.findObject("Objects", obj => obj.name === "Spawn Point"); + + var tilePos = new Phaser.Math.Vector2( + Math.floor(this.spawnPoint.x! / AkkamonWorldScene.TILE_SIZE), + Math.floor(this.spawnPoint.y! / AkkamonWorldScene.TILE_SIZE), + ); + this.spawnPointTilePos = tilePos; + + this.client.requestInitPlayerSprite( + this + ); + + let akey = this.input.keyboard.addKey('a'); + akey.on('down', () => { + this.activeMenu = new PauseMenu(this); + this.isUsingUIControls(); + }); + + } + + isUsingUIControls() { + this.client.setUIControls(); + } + + isUsingGridControls() { + this.client.setGridControls(); + } } diff --git a/client/src/akkamon/scenes/BootScene.ts b/client/src/akkamon/scenes/BootScene.ts index 4642584..5106ab8 100644 --- a/client/src/akkamon/scenes/BootScene.ts +++ b/client/src/akkamon/scenes/BootScene.ts @@ -26,13 +26,12 @@ export class BootScene extends AkkamonWorldScene { "assets/atlas/atlas.json"); this.load.image("menu", "assets/images/pMenu.png"); - this.load.image("menupicker", "assets/images/menupicker.png"); + this.load.image("picker", "assets/images/menupicker.png"); } create(): void { this.scene .launch('DemoScene') - .launch('AkkamonUI') .remove() } } diff --git a/client/src/akkamon/scenes/DemoScene.ts b/client/src/akkamon/scenes/DemoScene.ts index b9a230a..66da72f 100644 --- a/client/src/akkamon/scenes/DemoScene.ts +++ b/client/src/akkamon/scenes/DemoScene.ts @@ -11,38 +11,7 @@ export class DemoScene extends AkkamonWorldScene create () { - this.map = this.make.tilemap({ key: "map" }); - // Parameters are the name you gave the tileset in Tiled and then the key of the tileset image in - // Phaser's cache (i.e. the name you used in preload) - const tileset = this.map.addTilesetImage("akkamon-demo-extruded", "tiles"); - // Parameters: layer name (or index) from Tiled, tileset, x, y - const belowLayer = this.map.createLayer("Below Player", tileset, 0, 0); - const worldLayer = this.map.createLayer("World", tileset, 0, 0); - const aboveLayer = this.map.createLayer("Above Player", tileset, 0, 0); - // By default, everything gets depth sorted on the screen in the order we created things. Here, we - // want the "Above Player" layer to sit on top of the player, so we explicitly give it a depth. - // Higher depths will sit on top of lower depth objects. - aboveLayer.setDepth(10); - - this.spawnPoint = this.map.findObject("Objects", obj => obj.name === "Spawn Point"); - - var tilePos = new Phaser.Math.Vector2( - Math.floor(this.spawnPoint.x! / AkkamonWorldScene.TILE_SIZE), - Math.floor(this.spawnPoint.y! / AkkamonWorldScene.TILE_SIZE), - ); - this.spawnPointTilePos = tilePos; - - this.client.requestInitPlayerSprite( - this - ); - - let akey = this.input.keyboard.addKey('a'); - akey.on('down', () => { - this.input.keyboard.enabled = false; - this.eventsCenter.emit('open-menu'); - // this.client.disableGridControls(); - }); - + super.create("map", "akkamon-demo-extruded"); } diff --git a/client/src/akkamon/scenes/UIElement.ts b/client/src/akkamon/scenes/UIElement.ts index f48827d..0769dce 100644 --- a/client/src/akkamon/scenes/UIElement.ts +++ b/client/src/akkamon/scenes/UIElement.ts @@ -1,3 +1,141 @@ -export enum UIElement { - MAIN_MENU = "main-menu" +import type { AkkamonWorldScene } from '../scenes/AkkamonWorldScene'; +import { Direction } from '../render/Direction'; + + +class MenuText extends Phaser.GameObjects.Text { + constructor(scene: Phaser.Scene, group: Phaser.GameObjects.Group, x: number, y: number, text: string) { + let style: Phaser.Types.GameObjects.Text.TextStyle = { + fontFamily: 'Courier', + fontSize: '16px', + fontStyle: '', + backgroundColor: undefined, + color: '#000000', + stroke: '#000000', + strokeThickness: 0, + align: 'left', // 'left'|'center'|'right'|'justify' + } + super(scene, x, y, text, style); + console.log("adding text to scene"); + scene.add.existing(this); + group.add(this); + } +} + +class Picker extends Phaser.GameObjects.Image { + constructor(scene: Phaser.Scene, group: Phaser.GameObjects.Group, x: number, y: number, name: string) { + super(scene, x, y, name); + + this.setDisplaySize(20,33); + this.setOrigin(0.5,0.5); + scene.add.existing(this); + group.add(this); + } +} + +export interface AkkamonMenu { + selectButton: (direction: Direction) => void + destroyMe: () => void + confirm: () => void +} + + +class Menu extends Phaser.GameObjects.Image implements AkkamonMenu { + + private akkamonScene: AkkamonWorldScene + + public group?: Phaser.GameObjects.Group; + + private buttons?: Array<MenuText>; + + private picker?: Picker; + + private index?: number; + + destroyMe() { + console.log(this.group); + console.log("destroying group"); + this.group!.destroy(true); + this.akkamonScene.isUsingGridControls(); + } + + confirm() { + // communicate with client + } + + constructor(scene: AkkamonWorldScene) { + console.log("Making pause Menu"); + const { width, height } = scene.scale; + super(scene, width * 0.95, height * 0.05, "menu") + this.setOrigin(1,0) + this.setVisible(true) + this.setDisplaySize(296, 400) + + this.akkamonScene = scene; + + this.group = new Phaser.GameObjects.Group(scene); + + console.log("Adding this to scene"); + scene.add.existing(this); + this.group.add(this); + + this.buttons = new Array(); + + this.index = 0; + } + + setPicker(index: number) { + let pickerY = this.indexToYpixel(index); + if (!this.picker) { + let pickerX = this.x - this.displayWidth + 40; + this.picker = new Picker( + this.scene, + this.group!, + pickerX, + pickerY, + "picker") + } else { + this.picker.setY( + pickerY + ); + } + } + + private indexToYpixel(index: number) { + return index * 100 + 7; + } + + setButtons(buttonTextArray: Array<string>) { + for (let i = 0; i < buttonTextArray.length; i++) { + this.buttons!.push(new MenuText(this.scene, this.group!, this.x - 150, this.y + 40 + i * 100, buttonTextArray[i])); + } + } + + clearButtons() { + this.buttons = new Array(); + } + + selectButton(direction: Direction) { + if (direction === Direction.UP && this.index! !== 0) { + this.picker! + .setPosition(this.picker!.x, this.picker!.y - 100) + this.index! -= 1; + } else if (direction === Direction.DOWN && this.index !== this.buttons!.length - 1) { + this.picker! + .setPosition(this.picker!.x, this.picker!.y + 100) + this.index! += 1; + } + } +} + +export class PauseMenu extends Menu implements AkkamonMenu { + constructor(scene: AkkamonWorldScene) { + super(scene) + this.setPicker(0); + this.setButtons([ + 'POKéDEX', + 'POKéMON', + 'PHONE', + 'CLOSE' + ]); + } } diff --git a/client/src/akkamon/scenes/UIScene.ts b/client/src/akkamon/scenes/UIScene.ts index de415f8..199a847 100644 --- a/client/src/akkamon/scenes/UIScene.ts +++ b/client/src/akkamon/scenes/UIScene.ts @@ -1,125 +1,3 @@ import { Direction } from '../render/Direction'; import { eventsCenter } from '../../akkamon/scenes/AkkamonWorldScene'; -class MenuText extends Phaser.GameObjects.Text { - constructor(scene: Phaser.Scene, group: Phaser.GameObjects.Group, x: number, y: number, text: string) { - let style: Phaser.Types.GameObjects.Text.TextStyle = { - fontFamily: 'Courier', - fontSize: '16px', - fontStyle: '', - backgroundColor: undefined, - color: '#000000', - stroke: '#000000', - strokeThickness: 0, - align: 'left', // 'left'|'center'|'right'|'justify' - } - super(scene, x, y, text, style); - scene.add.existing(this); - group.add(this); - } -} - -interface AkkamonMenu { -} - -class Menu extends Phaser.GameObjects.Image implements AkkamonMenu { - - private buttons?: Array<MenuText>; - - private buttonSelector?: Phaser.GameObjects.Image; - - private selectedButton?: string; - - private index?: number; - - public group?: Phaser.GameObjects.Group; - - constructor(scene: Phaser.Scene) { - const { width, height } = scene.scale; - super(scene, width * 0.95, height * 0.05, "menu") - this.setOrigin(1,0) - this.setVisible(true) - this.setDisplaySize(296, 400) - - this.group = new Phaser.GameObjects.Group(scene); - - scene.add.existing(this); - this.group.add(this); - - this.buttons = new Array(); - - this.setMainButtons(); - - this.buttonSelector = scene.add.image( - this.x - this.displayWidth + 40, - this.buttons![0].y + 7, - "menupicker") - .setDisplaySize(20,33) - .setOrigin(0.5,0.5); - this.group.add(this.buttonSelector); - - this.index = 0; - this.selectedButton = this.buttons[0].text; - } - - resetPicker() { - this.buttonSelector! - .setPosition(this.x - this.displayWidth + 40, - this.buttons![0].y + 7); - } - - setMainButtons() { - this.buttons!.push(new MenuText(this.scene, this.group!, this.x - 150, this.y + 40, 'POKéDEX')); - this.buttons!.push(new MenuText(this.scene, this.group!, this.x - 150, this.y + 140, 'POKéMON')); - this.buttons!.push(new MenuText(this.scene, this.group!, this.x - 150, this.y + 240, 'PHONE')); - this.buttons!.push(new MenuText(this.scene, this.group!, this.x - 150, this.y + 340, 'CLOSE')); - } - - clearButtons() { - this.buttons = new Array(); - } - - selectButton(direction: Direction) { - if (direction === Direction.UP && this.index! !== 0) { - this.buttonSelector! - .setPosition(this.buttonSelector!.x, this.buttonSelector!.y - 100) - this.index! -= 1; - } else if (direction === Direction.DOWN && this.index !== this.buttons!.length - 1) { - this.buttonSelector! - .setPosition(this.buttonSelector!.x, this.buttonSelector!.y + 100) - this.index! += 1; - } - - this.selectedButton = this.buttons![this.index!].text; - } -} - -export class UIScene extends Phaser.Scene -{ - - // private uiControls: UIControls; - - private cursors?: Phaser.Types.Input.Keyboard.CursorKeys; - - private menu?: Menu; - - constructor () - { - super('AkkamonUI'); - } - - create () { - //this.uiControls = new UIControls(this.input); - - - this.menu = new Menu(this); - this.menu.group!.setVisible(false); - - eventsCenter.on('open-menu', () => - { - this.menu!.group!.setVisible(true); - }); - - } - -} |
