partey_workadventure/front/src/Phaser/Components/RadialMenu.ts

72 lines
2.4 KiB
TypeScript
Raw Normal View History

2021-05-10 17:10:41 +02:00
import Sprite = Phaser.GameObjects.Sprite;
import {DEPTH_UI_INDEX} from "../Game/DepthIndexes";
2021-05-19 18:08:53 +02:00
import {waScaleManager} from "../Services/WaScaleManager";
2021-05-10 17:10:41 +02:00
export interface RadialMenuItem {
sprite: string,
frame: number,
name: string,
}
2021-05-19 18:08:53 +02:00
const menuRadius = 60;
2021-05-10 17:10:41 +02:00
export const RadialMenuClickEvent = 'radialClick';
export class RadialMenu extends Phaser.GameObjects.Container {
2021-05-19 18:08:53 +02:00
private resizeCallback: OmitThisParameter<() => void>;
2021-05-10 17:10:41 +02:00
constructor(scene: Phaser.Scene, x: number, y: number, private items: RadialMenuItem[]) {
super(scene, x, y);
this.setDepth(DEPTH_UI_INDEX)
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
}
private initItems() {
const itemsNumber = this.items.length;
this.items.forEach((item, index) => this.createRadialElement(item, index, itemsNumber))
}
private createRadialElement(item: RadialMenuItem, index: number, itemsNumber: number) {
const image = new Sprite(this.scene, 0, menuRadius, item.sprite, item.frame);
this.add(image);
this.scene.sys.updateList.add(image);
image.setDepth(DEPTH_UI_INDEX)
image.setInteractive({
hitArea: new Phaser.Geom.Circle(0, 0, 25),
hitAreaCallback: Phaser.Geom.Circle.Contains, //eslint-disable-line @typescript-eslint/unbound-method
useHandCursor: true,
});
image.on('pointerdown', () => this.emit(RadialMenuClickEvent, item));
image.on('pointerover', () => {
this.scene.tweens.add({
targets: image,
scale: 2,
duration: 500,
ease: 'Power3',
})
});
image.on('pointerout', () => {
this.scene.tweens.add({
targets: image,
scale: 1,
duration: 500,
ease: 'Power3',
})
});
const angle = 2 * Math.PI * index / itemsNumber;
Phaser.Actions.RotateAroundDistance([image], {x: 0, y: 0}, angle, menuRadius);
}
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-05-10 17:10:41 +02:00
}