diff --git a/front/dist/resources/objects/customize.png b/front/dist/resources/objects/customize.png new file mode 100644 index 00000000..27cfe310 Binary files /dev/null and b/front/dist/resources/objects/customize.png differ diff --git a/front/dist/resources/objects/customize_selected.png b/front/dist/resources/objects/customize_selected.png new file mode 100644 index 00000000..060a6a8b Binary files /dev/null and b/front/dist/resources/objects/customize_selected.png differ diff --git a/front/src/Phaser/Game/GameManager.ts b/front/src/Phaser/Game/GameManager.ts index 04cb1bbe..f05857b4 100644 --- a/front/src/Phaser/Game/GameManager.ts +++ b/front/src/Phaser/Game/GameManager.ts @@ -14,11 +14,18 @@ export interface HasMovedEvent { export class GameManager { private playerName: string; - private characterUserSelected: string; + private characterLayers: string[]; - public storePlayerDetails(name: string, characterUserSelected : string): void { + public setPlayerName(name: string): void { this.playerName = name; - this.characterUserSelected = characterUserSelected; + } + + public setCharacterUserSelected(characterUserSelected : string): void { + this.characterLayers = [characterUserSelected]; + } + + public setCharacterLayers(layers: string[]) { + this.characterLayers = layers; } loadStartMap() : Promise { @@ -36,7 +43,7 @@ export class GameManager { } getCharacterSelected(): string { - return this.characterUserSelected; + return this.characterLayers[0]; } loadMap(mapUrl: string, scene: Phaser.Scenes.ScenePlugin, instance: string): string { diff --git a/front/src/Phaser/Login/CustomizeScene.ts b/front/src/Phaser/Login/CustomizeScene.ts index b28d11d7..fe59e205 100644 --- a/front/src/Phaser/Login/CustomizeScene.ts +++ b/front/src/Phaser/Login/CustomizeScene.ts @@ -5,6 +5,7 @@ import Rectangle = Phaser.GameObjects.Rectangle; import {LAYERS} from "../Entity/body_character"; import Sprite = Phaser.GameObjects.Sprite; import Container = Phaser.GameObjects.Container; +import {gameManager} from "../Game/GameManager"; export const CustomizeSceneName = "CustomizeScene"; @@ -15,10 +16,6 @@ enum CustomizeTextures{ arrowUp = "arrow_up", } -export interface CustomizeSceneInitDataInterface { - name: string -} - export class CustomizeScene extends Phaser.Scene { private textField: TextField; @@ -34,8 +31,6 @@ export class CustomizeScene extends Phaser.Scene { private logo: Image; - private loginName: String; - private selectedLayers: Array = [0]; private containersRow: Array> = new Array>(); private activeRow = 0; @@ -48,10 +43,6 @@ export class CustomizeScene extends Phaser.Scene { }); } - init({name}: CustomizeSceneInitDataInterface) { - this.loginName = name; - } - preload() { this.load.image(CustomizeTextures.arrowRight, "resources/objects/arrow_right.png"); this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png"); @@ -111,6 +102,19 @@ export class CustomizeScene extends Phaser.Scene { this.moveLayers(); this.input.keyboard.on('keyup-ENTER', () => { + const layers: string[] = []; + let i = 0; + for (let layerItem of this.selectedLayers) { + console.log(i, layerItem, LAYERS); + if (layerItem !== undefined) { + layers.push(LAYERS[i][layerItem].name); + } + i++; + } + + console.log(layers); + gameManager.setCharacterLayers(layers); + return this.scene.start(EnableCameraSceneName); }); @@ -251,10 +255,8 @@ export class CustomizeScene extends Phaser.Scene { const children = this.getContainerChildren(i, j); this.containersRow[i][j].removeAll(true); this.containersRow[i][j].add(children); - } } - } private reposition() { @@ -280,4 +282,4 @@ export class CustomizeScene extends Phaser.Scene { this.arrowRight.x = this.game.renderer.width*0.9; this.arrowRight.y = this.game.renderer.height/2; } -} \ No newline at end of file +} diff --git a/front/src/Phaser/Login/LoginScene.ts b/front/src/Phaser/Login/LoginScene.ts index 5177659b..308ba3ae 100644 --- a/front/src/Phaser/Login/LoginScene.ts +++ b/front/src/Phaser/Login/LoginScene.ts @@ -6,7 +6,7 @@ import Image = Phaser.GameObjects.Image; import Rectangle = Phaser.GameObjects.Rectangle; import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import {cypressAsserter} from "../../Cypress/CypressAsserter"; -import {SelectCharacterSceneInitDataInterface, SelectCharacterSceneName} from "./SelectCharacterScene"; +import {SelectCharacterSceneName} from "./SelectCharacterScene"; //todo: put this constants in a dedicated file export const LoginSceneName = "LoginScene"; @@ -89,6 +89,8 @@ export class LoginScene extends Phaser.Scene { } private login(name: string): void { - this.scene.start(SelectCharacterSceneName, { name } as SelectCharacterSceneInitDataInterface); + gameManager.setPlayerName(name); + + this.scene.start(SelectCharacterSceneName); } } diff --git a/front/src/Phaser/Login/SelectCharacterScene.ts b/front/src/Phaser/Login/SelectCharacterScene.ts index ddfd5c3b..535529ee 100644 --- a/front/src/Phaser/Login/SelectCharacterScene.ts +++ b/front/src/Phaser/Login/SelectCharacterScene.ts @@ -1,23 +1,22 @@ import {gameManager} from "../Game/GameManager"; import {TextField} from "../Components/TextField"; -import {ClickButton} from "../Components/ClickButton"; import Image = Phaser.GameObjects.Image; import Rectangle = Phaser.GameObjects.Rectangle; import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Character"; import {GameSceneInitInterface} from "../Game/GameScene"; import {StartMapInterface} from "../../Connection"; import {EnableCameraSceneName} from "./EnableCameraScene"; +import {CustomizeSceneName} from "./CustomizeScene"; + //todo: put this constants in a dedicated file export const SelectCharacterSceneName = "SelectCharacterScene"; enum LoginTextures { playButton = "play_button", icon = "icon", - mainFont = "main_font" -} - -export interface SelectCharacterSceneInitDataInterface { - name: string + mainFont = "main_font", + customizeButton = "customize_button", + customizeButtonSelected = "customize_button_selected" } export class SelectCharacterScene extends Phaser.Scene { @@ -25,12 +24,13 @@ export class SelectCharacterScene extends Phaser.Scene { private textField: TextField; private pressReturnField: TextField; private logo: Image; - private loginName: string; + private customizeButton: Image; + private customizeButtonSelected: Image; private selectedRectangle: Rectangle; private selectedRectangleXPos = 0; // Number of the character selected in the rows private selectedRectangleYPos = 0; // Number of the character selected in the columns - private selectedPlayer: Phaser.Physics.Arcade.Sprite; + private selectedPlayer: Phaser.Physics.Arcade.Sprite|null; // null if we are selecting the "customize" option private players: Array = new Array(); constructor() { @@ -39,10 +39,6 @@ export class SelectCharacterScene extends Phaser.Scene { }); } - init({ name }: SelectCharacterSceneInitDataInterface) { - this.loginName = name; - } - preload() { this.load.image(LoginTextures.playButton, "resources/objects/play_button.png"); this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png"); @@ -56,13 +52,15 @@ export class SelectCharacterScene extends Phaser.Scene { {frameWidth: 32, frameHeight: 32} ); }); + this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png'); + this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png'); } create() { this.textField = new TextField(this, this.game.renderer.width / 2, 50, 'Select your character'); this.textField.setOrigin(0.5).setCenterAlign() - this.pressReturnField = new TextField(this, this.game.renderer.width / 2, 230, 'Press enter to start'); + this.pressReturnField = new TextField(this, this.game.renderer.width / 2, 256, 'Press enter to start'); this.pressReturnField.setOrigin(0.5).setCenterAlign() const rectangleXStart = this.game.renderer.width / 2 - (this.nbCharactersPerRow / 2) * 32 + 16; @@ -73,7 +71,7 @@ export class SelectCharacterScene extends Phaser.Scene { this.add.existing(this.logo); this.input.keyboard.on('keyup-ENTER', () => { - return this.login(this.loginName); + return this.nextScene(); }); this.input.keyboard.on('keydown-RIGHT', () => { @@ -89,7 +87,7 @@ export class SelectCharacterScene extends Phaser.Scene { this.updateSelectedPlayer(); }); this.input.keyboard.on('keydown-DOWN', () => { - if (this.selectedRectangleYPos < Math.ceil(PLAYER_RESOURCES.length / this.nbCharactersPerRow) - 1) { + if (this.selectedRectangleYPos < Math.ceil(PLAYER_RESOURCES.length / this.nbCharactersPerRow)) { this.selectedRectangleYPos++; } this.updateSelectedPlayer(); @@ -117,10 +115,15 @@ export class SelectCharacterScene extends Phaser.Scene { this.pressReturnField.setVisible(!!(Math.floor(time / 500) % 2)); } - private login(name: string): void { - gameManager.storePlayerDetails(name, this.selectedPlayer.texture.key); + private nextScene(): void { - this.scene.start(EnableCameraSceneName); + if (this.selectedPlayer !== null) { + gameManager.setCharacterUserSelected(this.selectedPlayer.texture.key); + + this.scene.start(EnableCameraSceneName); + } else { + this.scene.start(CustomizeSceneName); + } // Do we have a start URL in the address bar? If so, let's redirect to this address /*const instanceAndMapUrl = this.findMapUrl(); @@ -188,6 +191,20 @@ export class SelectCharacterScene extends Phaser.Scene { }); this.players.push(player); } + + this.customizeButton = new Image(this, this.game.renderer.width / 2, 90 + 32 * 4 + 6, LoginTextures.customizeButton); + this.customizeButton.setOrigin(0.5, 0.5); + this.add.existing(this.customizeButton); + this.customizeButtonSelected = new Image(this, this.game.renderer.width / 2, 90 + 32 * 4 + 6, LoginTextures.customizeButtonSelected); + this.customizeButtonSelected.setOrigin(0.5, 0.5); + this.customizeButtonSelected.setVisible(false); + this.add.existing(this.customizeButtonSelected); + + this.customizeButton.setInteractive().on("pointerdown", () => { + this.selectedRectangleYPos = Math.ceil(PLAYER_RESOURCES.length / this.nbCharactersPerRow); + this.updateSelectedPlayer(); + }); + this.selectedPlayer = this.players[0]; this.selectedPlayer.play(PLAYER_RESOURCES[0].name); } @@ -203,10 +220,22 @@ export class SelectCharacterScene extends Phaser.Scene { } private updateSelectedPlayer(): void { - this.selectedPlayer.anims.pause(); + this.selectedPlayer?.anims.pause(); + // If we selected the customize button + if (this.selectedRectangleYPos === Math.ceil(PLAYER_RESOURCES.length / this.nbCharactersPerRow)) { + this.selectedPlayer = null; + this.selectedRectangle.setVisible(false); + this.customizeButtonSelected.setVisible(true); + this.customizeButton.setVisible(false); + return; + } + this.customizeButtonSelected.setVisible(false); + this.customizeButton.setVisible(true); const [x, y] = this.getCharacterPosition(this.selectedRectangleXPos, this.selectedRectangleYPos); + this.selectedRectangle.setVisible(true); this.selectedRectangle.setX(x); this.selectedRectangle.setY(y); + this.selectedRectangle.setSize(32, 32); const playerNumber = this.selectedRectangleXPos + this.selectedRectangleYPos * this.nbCharactersPerRow; const player = this.players[playerNumber]; player.play(PLAYER_RESOURCES[playerNumber].name); diff --git a/front/src/Phaser/Reconnecting/FourOFourScene.ts b/front/src/Phaser/Reconnecting/FourOFourScene.ts index 4fe4ff24..8c71ae65 100644 --- a/front/src/Phaser/Reconnecting/FourOFourScene.ts +++ b/front/src/Phaser/Reconnecting/FourOFourScene.ts @@ -1,7 +1,6 @@ import {TextField} from "../Components/TextField"; import Image = Phaser.GameObjects.Image; import Sprite = Phaser.GameObjects.Sprite; -import {SelectCharacterSceneInitDataInterface} from "../Login/SelectCharacterScene"; import Text = Phaser.GameObjects.Text; export const FourOFourSceneName = "FourOFourScene"; diff --git a/front/src/index.ts b/front/src/index.ts index a2ab575d..7634351f 100644 --- a/front/src/index.ts +++ b/front/src/index.ts @@ -15,7 +15,7 @@ const config: GameConfig = { width: window.innerWidth / RESOLUTION, height: window.innerHeight / RESOLUTION, parent: "game", - scene: [LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, FourOFourScene], + scene: [LoginScene, SelectCharacterScene, EnableCameraScene, ReconnectingScene, FourOFourScene, CustomizeScene], zoom: RESOLUTION, physics: { default: "arcade",