randomize and finish buttons
This commit is contained in:
parent
2cf55cac7e
commit
d971c7e064
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
53
front/src/Phaser/Components/Ui/Button.ts
Normal file
53
front/src/Phaser/Components/Ui/Button.ts
Normal 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);
|
||||
}
|
||||
}
|
@ -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<CustomWokaBodyPart, WokaBodyPartSlot>;
|
||||
|
||||
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) => {
|
||||
|
@ -35,45 +35,4 @@ export class MathUtils {
|
||||
public static randomFromArray<T>(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];
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user