diff --git a/front/dist/resources/objects/button.png b/front/dist/resources/objects/button.png new file mode 100644 index 00000000..cc69a02c Binary files /dev/null and b/front/dist/resources/objects/button.png differ diff --git a/front/dist/resources/objects/button_selected.png b/front/dist/resources/objects/button_selected.png new file mode 100644 index 00000000..31e4ed59 Binary files /dev/null and b/front/dist/resources/objects/button_selected.png differ diff --git a/front/src/Phaser/Components/ClickButton.ts b/front/src/Phaser/Components/ClickButton.ts index 204e9542..015d0dc3 100644 --- a/front/src/Phaser/Components/ClickButton.ts +++ b/front/src/Phaser/Components/ClickButton.ts @@ -1,11 +1,105 @@ +import {SpeechBubble} from "../Entity/SpeechBubble"; +import {PlayerAnimationNames} from "../Player/Animation"; +import Container = Phaser.GameObjects.Container; +import Image = Phaser.GameObjects.Image; +import BitmapText = Phaser.GameObjects.BitmapText; -export class ClickButton extends Phaser.GameObjects.Image{ - - constructor(scene: Phaser.Scene, x: number, y: number, textureName: string, callback: Function) { - super(scene, x, y, textureName); - this.scene.add.existing(this); - this.setInteractive(); - this.on("pointerup", callback); +export class ClickButton extends Container { + private button!: Image; + private text!: BitmapText; + private buttonSelected!: Image; + //private textSelected!: BitmapText; + private selected: boolean = false; + private callback: (() => void)|null = null; + private pointerOverCallback: (() => void)|null = null; + private pointerOutCallback: (() => void)|null = null; + + constructor(scene: Phaser.Scene, + x: number, + y: number, + label: string, + texture: string, + textureSelected: string, + ) { + super(scene, x, y/*, texture, frame*/); + + this.button = new Image(scene, 0, 0, texture); + this.buttonSelected = new Image(scene, 0, 0, textureSelected); + this.buttonSelected.setVisible(false); + this.text = new BitmapText(scene, 0, 0, 'main_font', label, 8); + this.text.setOrigin(0.5, 0.5); + //this.textSelected = new BitmapText(scene, 0, 0, 'main_font', label, 8); + //this.textSelected.setOrigin(0.5, 0.5); + this.add(this.button); + this.add(this.buttonSelected); + this.add(this.text); + + this.button.setInteractive(); + this.buttonSelected.setInteractive(); + + this.button.on("pointerover", () => { + if (this.pointerOverCallback === null) { + return; + } + this.pointerOverCallback(); + }); + + this.buttonSelected.on("pointerout", () => { + if (this.pointerOutCallback === null) { + return; + } + this.pointerOutCallback(); + }); + + this.buttonSelected.on('pointerup', () => { + if (this.callback === null) { + return; + } + this.callback(); + }); + this.button.on('pointerup', () => { + if (this.callback === null) { + return; + } + this.callback(); + }); } - -} \ No newline at end of file + + public select(): void { + this.selected = true; + this.switchToSelected(); + } + + private switchToSelected(): void { + this.button.setVisible(false); + this.buttonSelected.setVisible(true); + } + + public unselect(): void { + this.selected = false; + this.switchToNotSelected(); + } + + private switchToNotSelected(): void { + this.button.setVisible(true); + this.buttonSelected.setVisible(false); + } + + public onClick(callback: () => void) { + this.callback = callback; + } + + public onPointerOver(callback: () => void) { + this.pointerOverCallback = callback; + } + + public onPointerOut(callback: () => void) { + this.pointerOutCallback = callback; + } + + public click(): void { + if (this.callback !== null) { + this.callback(); + } + } +} diff --git a/front/src/Phaser/Login/MenuScene.ts b/front/src/Phaser/Login/MenuScene.ts new file mode 100644 index 00000000..1fec0f31 --- /dev/null +++ b/front/src/Phaser/Login/MenuScene.ts @@ -0,0 +1,110 @@ +import {gameManager} from "../Game/GameManager"; +import {TextField} from "../Components/TextField"; +import Image = Phaser.GameObjects.Image; +import {GameSceneInitInterface} from "../Game/GameScene"; +import {StartMapInterface} from "../../Connexion/ConnexionModels"; +import {mediaManager} from "../../WebRtc/MediaManager"; +import {RESOLUTION} from "../../Enum/EnvironmentVariable"; +import {SoundMeter} from "../Components/SoundMeter"; +import {SoundMeterSprite} from "../Components/SoundMeterSprite"; +import {ClickButton} from "../Components/ClickButton"; +import {ResizableScene} from "./ResizableScene"; + +export const MenuSceneName = "MenuScene"; +enum MenuTextures { + mainFont = "main_font", +} + +export class MenuScene extends ResizableScene { + private buttons: ClickButton[] = []; + private selected: number = 0; + + + constructor() { + super({ + key: MenuSceneName + }); + } + + preload() { + this.load.image('notSelectedButton', "resources/objects/button.png"); + this.load.image('selectedButton', "resources/objects/button_selected.png"); + this.load.bitmapFont(MenuTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); + } + + create() { + const changeName = new ClickButton(this, this.game.renderer.width / 2, 50, 'Edit name', 'notSelectedButton', 'selectedButton'); + changeName.onClick(() => { + console.log('Change name clicked') + }) + this.add.existing(changeName); + this.buttons.push(changeName); + + const changeCharacter = new ClickButton(this, this.game.renderer.width / 2, 100, 'Edit character', 'notSelectedButton', 'selectedButton'); + changeCharacter.onClick(() => { + console.log('changeCharacter clicked') + }) + this.add.existing(changeCharacter); + this.buttons.push(changeCharacter); + + const setupCamera = new ClickButton(this, this.game.renderer.width / 2, 150, 'Setup webcam', 'notSelectedButton', 'selectedButton'); + setupCamera.onClick(() => { + console.log('setupCamera clicked') + }) + this.add.existing(setupCamera); + this.buttons.push(setupCamera); + + const backToGame = new ClickButton(this, this.game.renderer.width / 2, 200, 'Back to game', 'notSelectedButton', 'selectedButton'); + backToGame.onClick(() => { + console.log('backToGame clicked') + }) + this.add.existing(backToGame); + this.buttons.push(backToGame); + + for (let i = 0; i < this.buttons.length; i++) { + const button = this.buttons[i]; + button.onPointerOver(() => { + this.selected = i; + this.select(); + }); + } + + this.select(); + + this.input.keyboard.on('keydown-DOWN', () => { + if (this.selected === this.buttons.length - 1) { + return; + } + this.selected++; + this.select(); + }); + this.input.keyboard.on('keydown-UP', () => { + if (this.selected === 0) { + return; + } + this.selected--; + this.select(); + }); + this.input.keyboard.on('keydown-ENTER', () => { + this.buttons[this.selected].click(); + }); + + } + + onResize(ev: UIEvent): void { + for (const button of this.buttons) { + button.setX(this.game.renderer.width / 2); + } + } + + private select(): void { + for (let i = 0; i < this.buttons.length; i++) { + const button = this.buttons[i]; + if (i === this.selected) { + button.select(); + } else { + button.unselect(); + } + } + } +} diff --git a/front/src/Phaser/Login/SelectCharacterScene.ts b/front/src/Phaser/Login/SelectCharacterScene.ts index e5df0a0d..3de6c923 100644 --- a/front/src/Phaser/Login/SelectCharacterScene.ts +++ b/front/src/Phaser/Login/SelectCharacterScene.ts @@ -6,6 +6,7 @@ import {PLAYER_RESOURCES, PlayerResourceDescriptionInterface} from "../Entity/Ch import {EnableCameraSceneName} from "./EnableCameraScene"; import {CustomizeSceneName} from "./CustomizeScene"; import {ResizableScene} from "./ResizableScene"; +import {ClickButton} from "../Components/ClickButton"; //todo: put this constants in a dedicated file @@ -23,8 +24,7 @@ export class SelectCharacterScene extends ResizableScene { private textField!: TextField; private pressReturnField!: TextField; private logo!: Image; - private customizeButton!: Image; - private customizeButtonSelected!: Image; + private customizeButton!: ClickButton; private selectedRectangle!: Rectangle; private selectedRectangleXPos = 0; // Number of the character selected in the rows @@ -53,6 +53,9 @@ export class SelectCharacterScene extends ResizableScene { }); this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png'); this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png'); + + this.load.image('notSelectedButton', "resources/objects/button.png"); + this.load.image('selectedButton', "resources/objects/button_selected.png"); } create() { @@ -191,13 +194,8 @@ export class SelectCharacterScene extends ResizableScene { 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.customizeButton = new ClickButton(this, this.game.renderer.width / 2, 90 + 32 * 4 + 6, 'Design your own', 'notSelectedButton', 'selectedButton'); 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); @@ -224,12 +222,10 @@ export class SelectCharacterScene extends ResizableScene { 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); + this.customizeButton.select(); return; } - this.customizeButtonSelected.setVisible(false); - this.customizeButton.setVisible(true); + this.customizeButton.unselect(); const [x, y] = this.getCharacterPosition(this.selectedRectangleXPos, this.selectedRectangleYPos); this.selectedRectangle.setVisible(true); this.selectedRectangle.setX(x); @@ -249,8 +245,7 @@ export class SelectCharacterScene extends ResizableScene { this.pressReturnField.x = this.game.renderer.width / 2; this.logo.x = this.game.renderer.width - 30; this.logo.y = this.game.renderer.height - 20; - this.customizeButton.x = this.game.renderer.width / 2; - this.customizeButtonSelected.x = this.game.renderer.width / 2; + this.customizeButton.setX(this.game.renderer.width / 2); for (let i = 0; i