2021-05-10 17:10:41 +02:00
|
|
|
import Sprite = Phaser.GameObjects.Sprite;
|
2021-09-06 14:27:54 +02:00
|
|
|
import { DEPTH_UI_INDEX } from "../Game/DepthIndexes";
|
|
|
|
import { waScaleManager } from "../Services/WaScaleManager";
|
2021-05-10 17:10:41 +02:00
|
|
|
|
|
|
|
export interface RadialMenuItem {
|
2021-09-06 14:27:54 +02:00
|
|
|
image: string;
|
|
|
|
name: string;
|
2021-05-10 17:10:41 +02:00
|
|
|
}
|
|
|
|
|
2021-09-06 14:27:54 +02:00
|
|
|
export const RadialMenuClickEvent = "radialClick";
|
2021-05-10 17:10:41 +02:00
|
|
|
|
|
|
|
export class RadialMenu extends Phaser.GameObjects.Container {
|
2021-05-19 18:08:53 +02:00
|
|
|
private resizeCallback: OmitThisParameter<() => void>;
|
2021-09-06 14:27:54 +02:00
|
|
|
|
2021-05-10 17:10:41 +02:00
|
|
|
constructor(scene: Phaser.Scene, x: number, y: number, private items: RadialMenuItem[]) {
|
|
|
|
super(scene, x, y);
|
2021-09-06 14:27:54 +02:00
|
|
|
this.setDepth(DEPTH_UI_INDEX);
|
2021-05-10 17:10:41 +02:00
|
|
|
this.scene.add.existing(this);
|
|
|
|
this.initItems();
|
2021-05-19 18:08:53 +02:00
|
|
|
|
|
|
|
this.resize();
|
|
|
|
this.resizeCallback = this.resize.bind(this);
|
|
|
|
this.scene.scale.on(Phaser.Scale.Events.RESIZE, this.resizeCallback);
|
2021-05-10 17:10:41 +02:00
|
|
|
}
|
2021-09-06 14:27:54 +02:00
|
|
|
|
2021-05-10 17:10:41 +02:00
|
|
|
private initItems() {
|
|
|
|
const itemsNumber = this.items.length;
|
2021-05-21 16:25:12 +02:00
|
|
|
const menuRadius = 70 + (waScaleManager.uiScalingFactor - 1) * 20;
|
2021-09-06 14:27:54 +02:00
|
|
|
this.items.forEach((item, index) => this.createRadialElement(item, index, itemsNumber, menuRadius));
|
2021-05-10 17:10:41 +02:00
|
|
|
}
|
2021-09-06 14:27:54 +02:00
|
|
|
|
2021-05-21 16:25:12 +02:00
|
|
|
private createRadialElement(item: RadialMenuItem, index: number, itemsNumber: number, menuRadius: number) {
|
2021-09-06 14:27:54 +02:00
|
|
|
const image = new Sprite(this.scene, 0, menuRadius, item.image);
|
2021-05-10 17:10:41 +02:00
|
|
|
this.add(image);
|
|
|
|
this.scene.sys.updateList.add(image);
|
2021-05-21 16:25:12 +02:00
|
|
|
const scalingFactor = waScaleManager.uiScalingFactor * 0.075;
|
2021-09-06 14:27:54 +02:00
|
|
|
image.setScale(scalingFactor);
|
2021-05-10 17:10:41 +02:00
|
|
|
image.setInteractive({
|
|
|
|
useHandCursor: true,
|
|
|
|
});
|
2021-09-06 14:27:54 +02:00
|
|
|
image.on("pointerdown", () => this.emit(RadialMenuClickEvent, item));
|
|
|
|
image.on("pointerover", () => {
|
2021-05-10 17:10:41 +02:00
|
|
|
this.scene.tweens.add({
|
|
|
|
targets: image,
|
2021-05-21 16:25:12 +02:00
|
|
|
props: {
|
|
|
|
scale: 2 * scalingFactor,
|
|
|
|
},
|
2021-05-10 17:10:41 +02:00
|
|
|
duration: 500,
|
2021-09-06 14:27:54 +02:00
|
|
|
ease: "Power3",
|
|
|
|
});
|
2021-05-10 17:10:41 +02:00
|
|
|
});
|
2021-09-06 14:27:54 +02:00
|
|
|
image.on("pointerout", () => {
|
2021-05-10 17:10:41 +02:00
|
|
|
this.scene.tweens.add({
|
|
|
|
targets: image,
|
2021-05-21 16:25:12 +02:00
|
|
|
props: {
|
|
|
|
scale: scalingFactor,
|
|
|
|
},
|
2021-05-10 17:10:41 +02:00
|
|
|
duration: 500,
|
2021-09-06 14:27:54 +02:00
|
|
|
ease: "Power3",
|
|
|
|
});
|
2021-05-10 17:10:41 +02:00
|
|
|
});
|
2021-09-06 14:27:54 +02:00
|
|
|
const angle = (2 * Math.PI * index) / itemsNumber;
|
|
|
|
Phaser.Actions.RotateAroundDistance([image], { x: 0, y: 0 }, angle, menuRadius);
|
2021-05-10 17:10:41 +02:00
|
|
|
}
|
2021-05-19 18:08:53 +02:00
|
|
|
|
|
|
|
private resize() {
|
|
|
|
this.setScale(waScaleManager.uiScalingFactor);
|
|
|
|
}
|
|
|
|
|
|
|
|
public destroy() {
|
|
|
|
this.scene.scale.removeListener(Phaser.Scale.Events.RESIZE, this.resizeCallback);
|
|
|
|
super.destroy();
|
|
|
|
}
|
2021-09-06 14:27:54 +02:00
|
|
|
}
|