improved radial menu

This commit is contained in:
kharhamel 2021-05-19 18:08:53 +02:00
parent 35b37a6a88
commit d93b30f982
6 changed files with 51 additions and 16 deletions

View File

@ -74,9 +74,6 @@ export class SocketManager {
clientEventsEmitter.registerToClientLeave((clientUUid: string, roomId: string) => { clientEventsEmitter.registerToClientLeave((clientUUid: string, roomId: string) => {
gaugeManager.decNbClientPerRoomGauge(roomId); gaugeManager.decNbClientPerRoomGauge(roomId);
}); });
//zoneMessageStream.stream.subscribe(myMessage);
} }
public async handleJoinRoom(socket: UserSocket, joinRoomMessage: JoinRoomMessage): Promise<{ room: GameRoom; user: User }> { public async handleJoinRoom(socket: UserSocket, joinRoomMessage: JoinRoomMessage): Promise<{ room: GameRoom; user: User }> {

View File

@ -1,5 +1,6 @@
import Sprite = Phaser.GameObjects.Sprite; import Sprite = Phaser.GameObjects.Sprite;
import {DEPTH_UI_INDEX} from "../Game/DepthIndexes"; import {DEPTH_UI_INDEX} from "../Game/DepthIndexes";
import {waScaleManager} from "../Services/WaScaleManager";
export interface RadialMenuItem { export interface RadialMenuItem {
sprite: string, sprite: string,
@ -7,16 +8,21 @@ export interface RadialMenuItem {
name: string, name: string,
} }
const menuRadius = 80; const menuRadius = 60;
export const RadialMenuClickEvent = 'radialClick'; export const RadialMenuClickEvent = 'radialClick';
export class RadialMenu extends Phaser.GameObjects.Container { export class RadialMenu extends Phaser.GameObjects.Container {
private resizeCallback: OmitThisParameter<() => void>;
constructor(scene: Phaser.Scene, x: number, y: number, private items: RadialMenuItem[]) { constructor(scene: Phaser.Scene, x: number, y: number, private items: RadialMenuItem[]) {
super(scene, x, y); super(scene, x, y);
this.setDepth(DEPTH_UI_INDEX) this.setDepth(DEPTH_UI_INDEX)
this.scene.add.existing(this); this.scene.add.existing(this);
this.initItems(); this.initItems();
this.resize();
this.resizeCallback = this.resize.bind(this);
this.scene.scale.on(Phaser.Scale.Events.RESIZE, this.resizeCallback);
} }
private initItems() { private initItems() {
@ -54,5 +60,13 @@ export class RadialMenu extends Phaser.GameObjects.Container {
const angle = 2 * Math.PI * index / itemsNumber; const angle = 2 * Math.PI * index / itemsNumber;
Phaser.Actions.RotateAroundDistance([image], {x: 0, y: 0}, angle, menuRadius); 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();
}
} }

View File

@ -6,8 +6,9 @@ import Sprite = Phaser.GameObjects.Sprite;
import {TextureError} from "../../Exception/TextureError"; import {TextureError} from "../../Exception/TextureError";
import {Companion} from "../Companion/Companion"; import {Companion} from "../Companion/Companion";
import {getEmoteAnimName} from "../Game/EmoteManager"; import {getEmoteAnimName} from "../Game/EmoteManager";
import {GameScene} from "../Game/GameScene"; import type {GameScene} from "../Game/GameScene";
import {DEPTH_INGAME_TEXT_INDEX} from "../Game/DepthIndexes"; import {DEPTH_INGAME_TEXT_INDEX} from "../Game/DepthIndexes";
import {waScaleManager} from "../Services/WaScaleManager";
const playerNameY = - 25; const playerNameY = - 25;
@ -19,7 +20,7 @@ interface AnimationData {
frames : number[] frames : number[]
} }
const interactiveRadius = 40; const interactiveRadius = 35;
export abstract class Character extends Container { export abstract class Character extends Container {
private bubble: SpeechBubble|null = null; private bubble: SpeechBubble|null = null;
@ -247,8 +248,9 @@ export abstract class Character extends Container {
this.cancelPreviousEmote(); this.cancelPreviousEmote();
this.playerName.setVisible(false); this.playerName.setVisible(false);
this.emote = new Sprite(this.scene, 0, -40, emoteKey, 1); this.emote = new Sprite(this.scene, 0, -30 - waScaleManager.uiScalingFactor * 10, emoteKey, 1);
this.emote.setDepth(DEPTH_INGAME_TEXT_INDEX); this.emote.setDepth(DEPTH_INGAME_TEXT_INDEX);
this.emote.setScale(waScaleManager.uiScalingFactor)
this.add(this.emote); this.add(this.emote);
this.scene.sys.updateList.add(this.emote); this.scene.sys.updateList.add(this.emote);
this.emote.play(getEmoteAnimName(emoteKey)); this.emote.play(getEmoteAnimName(emoteKey));

View File

@ -1,8 +1,8 @@
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; import type {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
import {createLoadingPromise} from "../Entity/PlayerTexturesLoadingManager"; import {createLoadingPromise} from "../Entity/PlayerTexturesLoadingManager";
import {emoteEventStream} from "../../Connexion/EmoteEventStream"; import {emoteEventStream} from "../../Connexion/EmoteEventStream";
import {GameScene} from "./GameScene"; import type {GameScene} from "./GameScene";
import {RadialMenuItem} from "../Components/RadialMenu"; import type {RadialMenuItem} from "../Components/RadialMenu";
enum RegisteredEmoteTypes { enum RegisteredEmoteTypes {
short = 1, short = 1,
@ -56,11 +56,11 @@ export class EmoteManager {
if (this.scene.anims.exists(getEmoteAnimName(textureKey))) { if (this.scene.anims.exists(getEmoteAnimName(textureKey))) {
return Promise.resolve(textureKey); return Promise.resolve(textureKey);
} }
const frameConfig = emoteDescriptor.type === RegisteredEmoteTypes.short ? {frames: [0,1,2]} : {frames : [0,1,2,3,4,5,6,7]}; const frameConfig = emoteDescriptor.type === RegisteredEmoteTypes.short ? {frames: [0,1,2,2]} : {frames : [0,1,2,3,4,]};
this.scene.anims.create({ this.scene.anims.create({
key: getEmoteAnimName(textureKey), key: getEmoteAnimName(textureKey),
frames: this.scene.anims.generateFrameNumbers(textureKey, frameConfig), frames: this.scene.anims.generateFrameNumbers(textureKey, frameConfig),
frameRate: 3, frameRate: 5,
repeat: 2, repeat: 2,
}); });
return textureKey; return textureKey;

View File

@ -11,6 +11,7 @@ export class Player extends Character {
private previousDirection: string = PlayerAnimationDirections.Down; private previousDirection: string = PlayerAnimationDirections.Down;
private wasMoving: boolean = false; private wasMoving: boolean = false;
private emoteMenu: RadialMenu|null = null; private emoteMenu: RadialMenu|null = null;
private updateListener: () => void;
constructor( constructor(
Scene: GameScene, Scene: GameScene,
@ -28,6 +29,14 @@ export class Player extends Character {
//the current player model should be push away by other players to prevent conflict //the current player model should be push away by other players to prevent conflict
this.getBody().setImmovable(false); this.getBody().setImmovable(false);
this.updateListener = () => {
if (this.emoteMenu) {
this.emoteMenu.x = this.x;
this.emoteMenu.y = this.y;
}
};
this.scene.events.addListener('postupdate', this.updateListener);
} }
moveUser(delta: number): void { moveUser(delta: number): void {
@ -97,13 +106,12 @@ export class Player extends Character {
openEmoteMenu(emotes:RadialMenuItem[]): void { openEmoteMenu(emotes:RadialMenuItem[]): void {
this.cancelPreviousEmote(); this.cancelPreviousEmote();
this.emoteMenu = new RadialMenu(this.scene, 0, 0, emotes) this.emoteMenu = new RadialMenu(this.scene, this.x, this.y, emotes)
this.emoteMenu.on(RadialMenuClickEvent, (item: RadialMenuItem) => { this.emoteMenu.on(RadialMenuClickEvent, (item: RadialMenuItem) => {
this.closeEmoteMenu(); this.closeEmoteMenu();
this.emit(requestEmoteEventName, item.name); this.emit(requestEmoteEventName, item.name);
this.playEmote(item.name); this.playEmote(item.name);
}) });
this.add(this.emoteMenu);
} }
closeEmoteMenu(): void { closeEmoteMenu(): void {
@ -111,4 +119,9 @@ export class Player extends Character {
this.emoteMenu.destroy(); this.emoteMenu.destroy();
this.emoteMenu = null; this.emoteMenu = null;
} }
destroy() {
this.scene.events.removeListener('postupdate', this.updateListener);
super.destroy();
}
} }

View File

@ -8,6 +8,7 @@ class WaScaleManager {
private hdpiManager: HdpiManager; private hdpiManager: HdpiManager;
private scaleManager!: ScaleManager; private scaleManager!: ScaleManager;
private game!: Game; private game!: Game;
private actualZoom: number = 1;
public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) { public constructor(private minGamePixelsNumber: number, private absoluteMinPixelNumber: number) {
this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber); this.hdpiManager = new HdpiManager(minGamePixelsNumber, absoluteMinPixelNumber);
@ -28,6 +29,7 @@ class WaScaleManager {
const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({width: width * devicePixelRatio, height: height * devicePixelRatio}); const { game: gameSize, real: realSize } = this.hdpiManager.getOptimalGameSize({width: width * devicePixelRatio, height: height * devicePixelRatio});
this.actualZoom = realSize.width / gameSize.width / devicePixelRatio;
this.scaleManager.setZoom(realSize.width / gameSize.width / devicePixelRatio); this.scaleManager.setZoom(realSize.width / gameSize.width / devicePixelRatio);
this.scaleManager.resize(gameSize.width, gameSize.height); this.scaleManager.resize(gameSize.width, gameSize.height);
@ -48,6 +50,13 @@ class WaScaleManager {
this.applyNewSize(); this.applyNewSize();
} }
/**
* This is used to scale back the ui components to counter-act the zoom.
*/
public get uiScalingFactor(): number {
return this.actualZoom > 1 ? 1 : 2;
}
} }
export const waScaleManager = new WaScaleManager(640*480, 196*196); export const waScaleManager = new WaScaleManager(640*480, 196*196);