randomize and finish buttons

This commit is contained in:
Piotr 'pwh' Hanusiak 2022-03-22 11:56:22 +01:00
parent 2cf55cac7e
commit d971c7e064
6 changed files with 178 additions and 70 deletions

View File

@ -56,6 +56,7 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container {
this.background = this.scene.add.graphics(); this.background = this.scene.add.graphics();
this.drawBackground(); this.drawBackground();
this.setSize(this.SIZE, this.SIZE); this.setSize(this.SIZE, this.SIZE);
this.setInteractive({ cursor: "pointer" });
this.add([ this.add([
this.background, this.background,
@ -67,6 +68,8 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container {
this.sprites.Accessory, this.sprites.Accessory,
]); ]);
this.bindEventHandlers();
this.scene.add.existing(this); this.scene.add.existing(this);
} }
@ -74,11 +77,6 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container {
this.animate(); 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 { public changeAnimation(direction: PlayerAnimationDirections, moving: boolean): void {
this.animationDirection = direction; this.animationDirection = direction;
this.moving = moving; this.moving = moving;
@ -112,6 +110,14 @@ export class CustomWokaPreviewer extends Phaser.GameObjects.Container {
return this.animationDirection; 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 { private drawBackground(): void {
this.background.clear(); this.background.clear();
this.background.fillStyle(0xffffff); 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;
}
}
} }

View File

@ -53,7 +53,7 @@ export class WokaBodyPartSlot extends GridItem {
this.add([this.background, this.bodyImage, this.image]); this.add([this.background, this.bodyImage, this.image]);
this.setInteractive(); this.setInteractive({ cursor: "pointer" });
this.scene.input.setDraggable(this); this.scene.input.setDraggable(this);
this.bindEventHandlers(); this.bindEventHandlers();

View File

@ -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);
}
}

View File

@ -25,6 +25,7 @@ import {
WokaBodyPartSlotEvent, WokaBodyPartSlotEvent,
} from "../Components/CustomizeWoka/WokaBodyPartSlot"; } from "../Components/CustomizeWoka/WokaBodyPartSlot";
import { DraggableGridEvent } from "@home-based-studio/phaser3-utils/lib/utils/gui/containers/grids/DraggableGrid"; import { DraggableGridEvent } from "@home-based-studio/phaser3-utils/lib/utils/gui/containers/grids/DraggableGrid";
import { Button } from "../Components/Ui/Button";
export const CustomizeSceneName = "CustomizeScene"; export const CustomizeSceneName = "CustomizeScene";
@ -35,6 +36,9 @@ export class CustomizeScene extends AbstractCharacterScene {
private bodyPartsDraggableGrid!: DraggableGrid; private bodyPartsDraggableGrid!: DraggableGrid;
private bodyPartsSlots!: Record<CustomWokaBodyPart, WokaBodyPartSlot>; private bodyPartsSlots!: Record<CustomWokaBodyPart, WokaBodyPartSlot>;
private randomizeButton!: Button;
private finishButton!: Button;
private selectedLayers: number[] = [0, 1, 2, 3, 4, 5]; private selectedLayers: number[] = [0, 1, 2, 3, 4, 5];
private containersRow: CustomizedCharacter[][] = []; private containersRow: CustomizedCharacter[][] = [];
private layers: BodyResourceDescriptionInterface[][] = []; private layers: BodyResourceDescriptionInterface[][] = [];
@ -42,8 +46,6 @@ export class CustomizeScene extends AbstractCharacterScene {
protected lazyloadingAttempt = true; //permit to update texture loaded after renderer protected lazyloadingAttempt = true; //permit to update texture loaded after renderer
private isVertical: boolean = false;
private loader: Loader; private loader: Loader;
constructor() { constructor() {
@ -97,9 +99,12 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
public create(): void { public create(): void {
this.isVertical = innerHeight / innerWidth > 1; this.customWokaPreviewer = new CustomWokaPreviewer(
this,
this.customWokaPreviewer = new CustomWokaPreviewer(this, 0, 0, this.getCustomWokaPreviewerConfig()); 0,
0,
this.getCustomWokaPreviewerConfig()
).setDisplaySize(200, 200);
this.bodyPartsDraggableGridBackground = this.add.graphics(); this.bodyPartsDraggableGridBackground = this.add.graphics();
@ -140,6 +145,9 @@ export class CustomizeScene extends AbstractCharacterScene {
[CustomWokaBodyPart.Eyes]: new WokaBodyPartSlot(this, 0, 0, this.getDefaultWokaBodyPartSlotConfig()), [CustomWokaBodyPart.Eyes]: new WokaBodyPartSlot(this, 0, 0, this.getDefaultWokaBodyPartSlotConfig()),
}; };
this.initializeRandomizeButton();
this.initializeFinishButton();
this.refreshPlayerCurrentOutfit(); this.refreshPlayerCurrentOutfit();
this.onResize(); this.onResize();
@ -148,15 +156,15 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
public update(time: number, dt: number): void { public update(time: number, dt: number): void {
// this.customWokaPreviewer.update(); this.customWokaPreviewer.update();
} }
public onResize(): void { public onResize(): void {
this.isVertical = innerHeight / innerWidth > 1;
this.handleCustomWokaPreviewerOnResize(); this.handleCustomWokaPreviewerOnResize();
this.handleBodyPartSlotsOnResize(); this.handleBodyPartSlotsOnResize();
this.handleBodyPartsDraggableGridOnResize(); this.handleBodyPartsDraggableGridOnResize();
this.handleRandomizeButtonOnResize();
this.handleFinishButtonOnResize();
} }
public nextSceneToCamera() { 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 { private refreshPlayerCurrentOutfit(): void {
let i = 0; let i = 0;
for (const layerItem of this.selectedLayers) { for (const layerItem of this.selectedLayers) {
@ -226,18 +280,13 @@ export class CustomizeScene extends AbstractCharacterScene {
} }
private handleCustomWokaPreviewerOnResize(): void { 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.x = this.cameras.main.worldView.x + this.cameras.main.width / 2;
this.customWokaPreviewer.y = this.isVertical this.customWokaPreviewer.y = this.customWokaPreviewer.displayHeight * 0.5 + 20;
? this.customWokaPreviewer.displayHeight * 0.5 + 20
: slotDimension * 1.5 + 20;
} }
private handleBodyPartSlotsOnResize(): void { private handleBodyPartSlotsOnResize(): void {
const ratio = innerHeight / innerWidth;
console.log(ratio);
const slotDimension = 100; const slotDimension = 100;
for (const part in this.bodyPartsSlots) { for (const part in this.bodyPartsSlots) {
@ -246,12 +295,12 @@ export class CustomizeScene extends AbstractCharacterScene {
const slotSize = this.bodyPartsSlots.Accessory.displayHeight; const slotSize = this.bodyPartsSlots.Accessory.displayHeight;
if (this.isVertical) { if (ratio > 1.6) {
const middle = Math.floor(this.customWokaPreviewer.x); const middle = Math.floor(this.customWokaPreviewer.x);
const left = Math.floor(middle - slotSize - 10); const left = Math.floor(middle - slotSize - 10);
const right = Math.floor(middle + slotSize + 10); const right = Math.floor(middle + slotSize + 10);
const top = Math.floor( 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); const bottom = Math.floor(top + slotSize + 10);
@ -265,11 +314,13 @@ export class CustomizeScene extends AbstractCharacterScene {
return; return;
} }
const ratio = innerHeight / innerWidth; const left = Math.floor(
this.customWokaPreviewer.x - this.customWokaPreviewer.displayWidth * 0.5 - slotSize * 0.5 - 10
const left = Math.floor(this.customWokaPreviewer.x - this.customWokaPreviewer.displayWidth * 0.5 - slotSize); );
const leftEdge = Math.floor(left - slotSize - 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 rightEdge = Math.floor(right + slotSize + 10);
const top = Math.floor(0 + slotSize * 0.5 + 10); const top = Math.floor(0 + slotSize * 0.5 + 10);
const middle = Math.floor(top + slotSize + 10); const middle = Math.floor(top + slotSize + 10);
@ -299,6 +350,28 @@ export class CustomizeScene extends AbstractCharacterScene {
this.bodyPartsDraggableGrid.moveContentToBeginning(); 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 { private getCustomWokaPreviewerConfig(): CustomWokaPreviewerConfig {
return { return {
color: 0xffffff, color: 0xffffff,
@ -332,13 +405,17 @@ export class CustomizeScene extends AbstractCharacterScene {
this.backToPreviousScene(); this.backToPreviousScene();
}); });
this.input.keyboard.on("keydown-R", () => { this.randomizeButton.on(Phaser.Input.Events.POINTER_UP, () => {
this.randomizeOutfit(); this.randomizeOutfit();
this.clearGrid(); this.clearGrid();
this.deselectAllSlots(); this.deselectAllSlots();
this.refreshPlayerCurrentOutfit(); this.refreshPlayerCurrentOutfit();
}); });
this.finishButton.on(Phaser.Input.Events.POINTER_UP, () => {
this.nextSceneToCamera();
});
for (const bodyPart in CustomWokaBodyPart) { for (const bodyPart in CustomWokaBodyPart) {
const slot = this.bodyPartsSlots[bodyPart as CustomWokaBodyPart]; const slot = this.bodyPartsSlots[bodyPart as CustomWokaBodyPart];
slot.on(WokaBodyPartSlotEvent.Clicked, (selected: boolean) => { slot.on(WokaBodyPartSlotEvent.Clicked, (selected: boolean) => {

View File

@ -35,45 +35,4 @@ export class MathUtils {
public static randomFromArray<T>(array: T[]): T { public static randomFromArray<T>(array: T[]): T {
return array[Math.floor(Math.random() * array.length)]; 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];
}
} }