import Sprite = Phaser.GameObjects.Sprite; import {DEPTH_UI_INDEX} from "../Game/DepthIndexes"; import {waScaleManager} from "../Services/WaScaleManager"; export interface RadialMenuItem { image: string, name: string, } export const RadialMenuClickEvent = 'radialClick'; export class RadialMenu extends Phaser.GameObjects.Container { private resizeCallback: OmitThisParameter<() => void>; 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(); this.resize(); this.resizeCallback = this.resize.bind(this); this.scene.scale.on(Phaser.Scale.Events.RESIZE, this.resizeCallback); } private initItems() { const itemsNumber = this.items.length; const menuRadius = 70 + (waScaleManager.uiScalingFactor - 1) * 20; this.items.forEach((item, index) => this.createRadialElement(item, index, itemsNumber, menuRadius)) } private createRadialElement(item: RadialMenuItem, index: number, itemsNumber: number, menuRadius: number) { const image = new Sprite(this.scene, 0, menuRadius, item.image); this.add(image); this.scene.sys.updateList.add(image); const scalingFactor = waScaleManager.uiScalingFactor * 0.075; image.setScale(scalingFactor) image.setInteractive({ useHandCursor: true, }); image.on('pointerdown', () => this.emit(RadialMenuClickEvent, item)); image.on('pointerover', () => { this.scene.tweens.add({ targets: image, props: { scale: 2 * scalingFactor, }, duration: 500, ease: 'Power3', }) }); image.on('pointerout', () => { this.scene.tweens.add({ targets: image, props: { scale: scalingFactor, }, duration: 500, ease: 'Power3', }) }); const angle = 2 * Math.PI * index / itemsNumber; Phaser.Actions.RotateAroundDistance([image], {x: 0, y: 0}, angle, menuRadius); } private resize() { this.setScale(waScaleManager.uiScalingFactor); } public destroy() { this.scene.scale.removeListener(Phaser.Scale.Events.RESIZE, this.resizeCallback); super.destroy(); } }