From d971c7e064d19ae27e0a05a341a6b757897ffcef Mon Sep 17 00:00:00 2001 From: Piotr 'pwh' Hanusiak Date: Tue, 22 Mar 2022 11:56:22 +0100 Subject: [PATCH] randomize and finish buttons --- .../CustomizeWoka/CustomWokaPreviewer.ts | 29 ++++- .../CustomizeWoka/WokaBodyPartSlot.ts | 2 +- front/src/Phaser/Components/Ui/Button.ts | 53 ++++++++ .../src/Phaser/Components/Ui/StatesButton.ts | 0 front/src/Phaser/Login/CustomizeScene.ts | 123 ++++++++++++++---- front/src/Utils/MathUtils.ts | 41 ------ 6 files changed, 178 insertions(+), 70 deletions(-) create mode 100644 front/src/Phaser/Components/Ui/Button.ts delete mode 100644 front/src/Phaser/Components/Ui/StatesButton.ts diff --git a/front/src/Phaser/Components/CustomizeWoka/CustomWokaPreviewer.ts b/front/src/Phaser/Components/CustomizeWoka/CustomWokaPreviewer.ts index a0eb4e9a..828e03ec 100644 --- a/front/src/Phaser/Components/CustomizeWoka/CustomWokaPreviewer.ts +++ b/front/src/Phaser/Components/CustomizeWoka/CustomWokaPreviewer.ts @@ -56,6 +56,7 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container { this.background = this.scene.add.graphics(); this.drawBackground(); this.setSize(this.SIZE, this.SIZE); + this.setInteractive({ cursor: "pointer" }); this.add([ this.background, @@ -67,6 +68,8 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container { this.sprites.Accessory, ]); + this.bindEventHandlers(); + this.scene.add.existing(this); } @@ -74,11 +77,6 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container { this.animate(); } - // public setDisplaySize(width: number, height: number): this { - // const [newWidth, newHeight] = MathUtils.getWholePixelsNewSize(this.SIZE, this.SIZE, width, height); - // return super.setDisplaySize(newWidth, newHeight); - // } - public changeAnimation(direction: PlayerAnimationDirections, moving: boolean): void { this.animationDirection = direction; this.moving = moving; @@ -112,6 +110,14 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container { return this.animationDirection; } + private bindEventHandlers(): void { + this.on(Phaser.Input.Events.POINTER_UP, () => { + const direction = this.getNextAnimationDirection(); + const moving = direction === PlayerAnimationDirections.Down ? !this.moving : this.moving; + this.changeAnimation(direction, moving); + }); + } + private drawBackground(): void { this.background.clear(); this.background.fillStyle(0xffffff); @@ -142,4 +148,17 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container { } } } + + private getNextAnimationDirection(): PlayerAnimationDirections { + switch (this.animationDirection) { + case PlayerAnimationDirections.Down: + return PlayerAnimationDirections.Left; + case PlayerAnimationDirections.Left: + return PlayerAnimationDirections.Up; + case PlayerAnimationDirections.Up: + return PlayerAnimationDirections.Right; + case PlayerAnimationDirections.Right: + return PlayerAnimationDirections.Down; + } + } } diff --git a/front/src/Phaser/Components/CustomizeWoka/WokaBodyPartSlot.ts b/front/src/Phaser/Components/CustomizeWoka/WokaBodyPartSlot.ts index f71b7ad1..14fc865b 100644 --- a/front/src/Phaser/Components/CustomizeWoka/WokaBodyPartSlot.ts +++ b/front/src/Phaser/Components/CustomizeWoka/WokaBodyPartSlot.ts @@ -53,7 +53,7 @@ export class WokaBodyPartSlot extends GridItem { this.add([this.background, this.bodyImage, this.image]); - this.setInteractive(); + this.setInteractive({ cursor: "pointer" }); this.scene.input.setDraggable(this); this.bindEventHandlers(); diff --git a/front/src/Phaser/Components/Ui/Button.ts b/front/src/Phaser/Components/Ui/Button.ts new file mode 100644 index 00000000..6fb39571 --- /dev/null +++ b/front/src/Phaser/Components/Ui/Button.ts @@ -0,0 +1,53 @@ +export interface ButtonConfig { + width: number; + height: number; + idle: ButtonAppearanceConfig; + hover: ButtonAppearanceConfig; + pressed: ButtonAppearanceConfig; +} + +export interface ButtonAppearanceConfig { + color: number; + borderThickness: number; + borderColor: number; +} + +export class Button extends Phaser.GameObjects.Container { + private background: Phaser.GameObjects.Graphics; + private text: Phaser.GameObjects.Text; + + private config: ButtonConfig; + + constructor(scene: Phaser.Scene, x: number, y: number, config: ButtonConfig) { + super(scene, x, y); + + this.config = config; + + this.background = this.scene.add.graphics(); + this.drawBackground(this.config.idle); + this.text = this.scene.add.text(0, 0, "", { color: "0x000000" }).setOrigin(0.5); + + this.add([this.background, this.text]); + + this.setSize(this.config.width, this.config.height); + this.setInteractive({ cursor: "pointer" }); + + this.scene.add.existing(this); + } + + public setText(text: string): void { + this.text.setText(text); + } + + private drawBackground(appearance: ButtonAppearanceConfig): void { + this.background.clear(); + this.background.fillStyle(appearance.color); + this.background.lineStyle(appearance.borderThickness, appearance.borderColor); + + const w = this.config.width; + const h = this.config.height; + + this.background.fillRect(-w / 2, -h / 2, w, h); + this.background.strokeRect(-w / 2, -h / 2, w, h); + } +} diff --git a/front/src/Phaser/Components/Ui/StatesButton.ts b/front/src/Phaser/Components/Ui/StatesButton.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/front/src/Phaser/Login/CustomizeScene.ts b/front/src/Phaser/Login/CustomizeScene.ts index 0a449fb3..7dfb1fb2 100644 --- a/front/src/Phaser/Login/CustomizeScene.ts +++ b/front/src/Phaser/Login/CustomizeScene.ts @@ -25,6 +25,7 @@ import { WokaBodyPartSlotEvent, } from "../Components/CustomizeWoka/WokaBodyPartSlot"; import { DraggableGridEvent } from "@home-based-studio/phaser3-utils/lib/utils/gui/containers/grids/DraggableGrid"; +import { Button } from "../Components/Ui/Button"; export const CustomizeSceneName = "CustomizeScene"; @@ -35,6 +36,9 @@ export class CustomizeScene extends AbstractCharacterScene { private bodyPartsDraggableGrid!: DraggableGrid; private bodyPartsSlots!: Record; + private randomizeButton!: Button; + private finishButton!: Button; + private selectedLayers: number[] = [0, 1, 2, 3, 4, 5]; private containersRow: CustomizedCharacter[][] = []; private layers: BodyResourceDescriptionInterface[][] = []; @@ -42,8 +46,6 @@ export class CustomizeScene extends AbstractCharacterScene { protected lazyloadingAttempt = true; //permit to update texture loaded after renderer - private isVertical: boolean = false; - private loader: Loader; constructor() { @@ -97,9 +99,12 @@ export class CustomizeScene extends AbstractCharacterScene { } public create(): void { - this.isVertical = innerHeight / innerWidth > 1; - - this.customWokaPreviewer = new CustomWokaPreviewer(this, 0, 0, this.getCustomWokaPreviewerConfig()); + this.customWokaPreviewer = new CustomWokaPreviewer( + this, + 0, + 0, + this.getCustomWokaPreviewerConfig() + ).setDisplaySize(200, 200); this.bodyPartsDraggableGridBackground = this.add.graphics(); @@ -140,6 +145,9 @@ export class CustomizeScene extends AbstractCharacterScene { [CustomWokaBodyPart.Eyes]: new WokaBodyPartSlot(this, 0, 0, this.getDefaultWokaBodyPartSlotConfig()), }; + this.initializeRandomizeButton(); + this.initializeFinishButton(); + this.refreshPlayerCurrentOutfit(); this.onResize(); @@ -148,15 +156,15 @@ export class CustomizeScene extends AbstractCharacterScene { } public update(time: number, dt: number): void { - // this.customWokaPreviewer.update(); + this.customWokaPreviewer.update(); } public onResize(): void { - this.isVertical = innerHeight / innerWidth > 1; - this.handleCustomWokaPreviewerOnResize(); this.handleBodyPartSlotsOnResize(); this.handleBodyPartsDraggableGridOnResize(); + this.handleRandomizeButtonOnResize(); + this.handleFinishButtonOnResize(); } public nextSceneToCamera() { @@ -212,6 +220,52 @@ export class CustomizeScene extends AbstractCharacterScene { ); } + private initializeRandomizeButton(): void { + this.randomizeButton = new Button(this, 50, 50, { + width: 95, + height: 50, + idle: { + color: 0xffffff, + borderThickness: 1, + borderColor: 0xadafbc, + }, + hover: { + color: 0xffffff, + borderThickness: 1, + borderColor: 0xadafbc, + }, + pressed: { + color: 0xffffff, + borderThickness: 1, + borderColor: 0xadafbc, + }, + }); + this.randomizeButton.setText("Randomize"); + } + + private initializeFinishButton(): void { + this.finishButton = new Button(this, 50, 50, { + width: 95, + height: 50, + idle: { + color: 0xffffff, + borderThickness: 1, + borderColor: 0xadafbc, + }, + hover: { + color: 0xffffff, + borderThickness: 1, + borderColor: 0xadafbc, + }, + pressed: { + color: 0xffffff, + borderThickness: 1, + borderColor: 0xadafbc, + }, + }); + this.finishButton.setText("Finish"); + } + private refreshPlayerCurrentOutfit(): void { let i = 0; for (const layerItem of this.selectedLayers) { @@ -226,18 +280,13 @@ export class CustomizeScene extends AbstractCharacterScene { } private handleCustomWokaPreviewerOnResize(): void { - const slotDimension = 100; - - const boxDimension = 200; - - this.customWokaPreviewer.setDisplaySize(boxDimension, boxDimension); this.customWokaPreviewer.x = this.cameras.main.worldView.x + this.cameras.main.width / 2; - this.customWokaPreviewer.y = this.isVertical - ? this.customWokaPreviewer.displayHeight * 0.5 + 20 - : slotDimension * 1.5 + 20; + this.customWokaPreviewer.y = this.customWokaPreviewer.displayHeight * 0.5 + 20; } private handleBodyPartSlotsOnResize(): void { + const ratio = innerHeight / innerWidth; + console.log(ratio); const slotDimension = 100; for (const part in this.bodyPartsSlots) { @@ -246,12 +295,12 @@ export class CustomizeScene extends AbstractCharacterScene { const slotSize = this.bodyPartsSlots.Accessory.displayHeight; - if (this.isVertical) { + if (ratio > 1.6) { const middle = Math.floor(this.customWokaPreviewer.x); const left = Math.floor(middle - slotSize - 10); const right = Math.floor(middle + slotSize + 10); const top = Math.floor( - this.customWokaPreviewer.y + this.customWokaPreviewer.displayHeight * 0.5 + slotSize * 0.5 + 10 + this.customWokaPreviewer.y + this.customWokaPreviewer.displayHeight * 0.5 + slotSize * 1.5 + 10 ); const bottom = Math.floor(top + slotSize + 10); @@ -265,11 +314,13 @@ export class CustomizeScene extends AbstractCharacterScene { return; } - const ratio = innerHeight / innerWidth; - - const left = Math.floor(this.customWokaPreviewer.x - this.customWokaPreviewer.displayWidth * 0.5 - slotSize); + const left = Math.floor( + this.customWokaPreviewer.x - this.customWokaPreviewer.displayWidth * 0.5 - slotSize * 0.5 - 10 + ); const leftEdge = Math.floor(left - slotSize - 10); - const right = Math.floor(this.customWokaPreviewer.x + this.customWokaPreviewer.displayWidth * 0.5 + slotSize); + const right = Math.floor( + this.customWokaPreviewer.x + this.customWokaPreviewer.displayWidth * 0.5 + slotSize * 0.5 + 10 + ); const rightEdge = Math.floor(right + slotSize + 10); const top = Math.floor(0 + slotSize * 0.5 + 10); const middle = Math.floor(top + slotSize + 10); @@ -299,6 +350,28 @@ export class CustomizeScene extends AbstractCharacterScene { this.bodyPartsDraggableGrid.moveContentToBeginning(); } + private handleRandomizeButtonOnResize(): void { + const x = + this.customWokaPreviewer.x + + (this.customWokaPreviewer.displayWidth - this.randomizeButton.displayWidth) * 0.5; + const y = + this.customWokaPreviewer.y + + (this.customWokaPreviewer.displayHeight + this.randomizeButton.displayHeight) * 0.5 + + 10; + this.randomizeButton.setPosition(x, y); + } + + private handleFinishButtonOnResize(): void { + const x = + this.customWokaPreviewer.x - + (this.customWokaPreviewer.displayWidth - this.randomizeButton.displayWidth) * 0.5; + const y = + this.customWokaPreviewer.y + + (this.customWokaPreviewer.displayHeight + this.randomizeButton.displayHeight) * 0.5 + + 10; + this.finishButton.setPosition(x, y); + } + private getCustomWokaPreviewerConfig(): CustomWokaPreviewerConfig { return { color: 0xffffff, @@ -332,13 +405,17 @@ export class CustomizeScene extends AbstractCharacterScene { this.backToPreviousScene(); }); - this.input.keyboard.on("keydown-R", () => { + this.randomizeButton.on(Phaser.Input.Events.POINTER_UP, () => { this.randomizeOutfit(); this.clearGrid(); this.deselectAllSlots(); this.refreshPlayerCurrentOutfit(); }); + this.finishButton.on(Phaser.Input.Events.POINTER_UP, () => { + this.nextSceneToCamera(); + }); + for (const bodyPart in CustomWokaBodyPart) { const slot = this.bodyPartsSlots[bodyPart as CustomWokaBodyPart]; slot.on(WokaBodyPartSlotEvent.Clicked, (selected: boolean) => { diff --git a/front/src/Utils/MathUtils.ts b/front/src/Utils/MathUtils.ts index 77e184cd..fc055d11 100644 --- a/front/src/Utils/MathUtils.ts +++ b/front/src/Utils/MathUtils.ts @@ -35,45 +35,4 @@ export class MathUtils { public static randomFromArray(array: T[]): T { return array[Math.floor(Math.random() * array.length)]; } - - /** - * - * @param baseWidth Object's default width not affected by any scaling - * @param baseHeight Object's default height not affected by any scaling - * @param requestedWidth Width we would like to achieve - * @param requestedHeight Height we would like to achieve - * @param unitSizeWidth Smallest possible unit of our 'scale step' for width - * @param unitSizeHeight Smallest possible unit of our 'scale step' for height - * @returns [ newWidth, newHeight ] - */ - public static getWholePixelsNewSize( - baseWidth: number, - baseHeight: number, - requestedWidth: number, - requestedHeight: number, - unitSizeWidth: number = 32, - unitSizeHeight: number = 32 - ): [number, number] { - // Demanded scale to be applied - const newScaleW = requestedWidth / baseWidth; - const newScaleH = requestedHeight / baseHeight; - - // How would it affect our sprites - const spriteWidth = Math.floor(unitSizeWidth * newScaleW); - const spriteHeight = Math.floor(unitSizeHeight * newScaleH); - - const restWidth = spriteWidth % unitSizeWidth; - const restHeight = spriteWidth % unitSizeHeight; - - // Expected nearest sprite size to maintain crisp pixels - const expectedSpriteWidth = spriteWidth - restWidth + (restWidth > unitSizeWidth / 2 ? unitSizeWidth : 0); - const expectedSpriteHeight = spriteHeight - restHeight + (restHeight > unitSizeHeight / 2 ? unitSizeHeight : 0); - - // Expected nearest scale - const neededScaleWidth = expectedSpriteWidth / unitSizeWidth; - const neededScaleHeight = expectedSpriteHeight / unitSizeHeight; - - // Calculate new width and height and apply it to the whole container - return [baseWidth * neededScaleWidth, baseHeight * neededScaleHeight]; - } }