use emote button
This commit is contained in:
parent
83bd19c8dc
commit
f43deff626
9 changed files with 329 additions and 202 deletions
|
@ -1,63 +1,50 @@
|
|||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import Text = Phaser.GameObjects.Text;
|
||||
import {DEPTH_UI_INDEX} from "../Game/DepthIndexes";
|
||||
import {waScaleManager} from "../Services/WaScaleManager";
|
||||
import DOMElement = Phaser.GameObjects.DOMElement;
|
||||
import { DEPTH_UI_INDEX } from "../Game/DepthIndexes";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import { EmojiButton } from "@joeattardi/emoji-button";
|
||||
import { HtmlUtils } from "../../WebRtc/HtmlUtils";
|
||||
|
||||
export const EmoteMenuClickEvent = 'emoteClick';
|
||||
export const EmoteMenuClickEvent = "emoteClick";
|
||||
|
||||
export class EmoteMenu extends Phaser.GameObjects.Container {
|
||||
private resizeCallback: OmitThisParameter<() => void>;
|
||||
private container: DOMElement;
|
||||
private picker: EmojiButton;
|
||||
|
||||
constructor(scene: Phaser.Scene, x: number, y: number, private items: string[]) {
|
||||
constructor(scene: Phaser.Scene, x: number, y: number) {
|
||||
super(scene, x, y);
|
||||
this.setDepth(DEPTH_UI_INDEX)
|
||||
this.setDepth(DEPTH_UI_INDEX);
|
||||
this.scene.add.existing(this);
|
||||
this.initItems();
|
||||
this.container = new DOMElement(this.scene, 0, 0, "div", "", "");
|
||||
this.container.setClassName("emoji-container");
|
||||
const scalingFactor = waScaleManager.uiScalingFactor * 0.5;
|
||||
this.container.setScale(scalingFactor);
|
||||
this.add(this.container);
|
||||
const emojiContainer = HtmlUtils.querySelectorOrFail(".emoji-container");
|
||||
this.picker = new EmojiButton({ rootElement: emojiContainer });
|
||||
|
||||
this.picker.on("emoji", (selection) => {
|
||||
this.emit(EmoteMenuClickEvent, selection.emoji);
|
||||
});
|
||||
|
||||
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.createEmoteElement(item, index, itemsNumber, menuRadius))
|
||||
public isOpen(): boolean {
|
||||
return this.picker.isPickerVisible();
|
||||
}
|
||||
|
||||
private createEmoteElement(item: string, index: number, itemsNumber: number, menuRadius: number) {
|
||||
// const image = new Sprite(this.scene, 0, menuRadius, item.image);
|
||||
const image = new Text(this.scene, -12, menuRadius, item, {fontFamily: '"twemoji"', fontSize:'75px'});
|
||||
this.add(image);
|
||||
// this.scene.sys.updateList.add(image);
|
||||
const scalingFactor = waScaleManager.uiScalingFactor * 0.3;
|
||||
image.setScale(scalingFactor)
|
||||
image.setInteractive({
|
||||
useHandCursor: true,
|
||||
});
|
||||
image.on('pointerdown', () => this.emit(EmoteMenuClickEvent, item));
|
||||
image.on('pointerover', () => {
|
||||
this.scene.tweens.add({
|
||||
targets: image,
|
||||
props: {
|
||||
scale: 1.5 * 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: -12, y: -12}, angle, menuRadius);
|
||||
public openPicker() {
|
||||
const emojiContainer = HtmlUtils.querySelectorOrFail(".emoji-container");
|
||||
this.picker.showPicker(emojiContainer);
|
||||
}
|
||||
|
||||
public closePicker() {
|
||||
this.picker.hidePicker();
|
||||
}
|
||||
|
||||
private resize() {
|
||||
|
@ -68,4 +55,4 @@ export class EmoteMenu extends Phaser.GameObjects.Container {
|
|||
this.scene.scale.removeListener(Phaser.Scale.Events.RESIZE, this.resizeCallback);
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
import {PlayerAnimationDirections, PlayerAnimationTypes} from "../Player/Animation";
|
||||
import {SpeechBubble} from "./SpeechBubble";
|
||||
import { PlayerAnimationDirections, PlayerAnimationTypes } from "../Player/Animation";
|
||||
import { SpeechBubble } from "./SpeechBubble";
|
||||
import Text = Phaser.GameObjects.Text;
|
||||
import Container = Phaser.GameObjects.Container;
|
||||
import Sprite = Phaser.GameObjects.Sprite;
|
||||
import {TextureError} from "../../Exception/TextureError";
|
||||
import {Companion} from "../Companion/Companion";
|
||||
import type {GameScene} from "../Game/GameScene";
|
||||
import {DEPTH_INGAME_TEXT_INDEX} from "../Game/DepthIndexes";
|
||||
import {waScaleManager} from "../Services/WaScaleManager";
|
||||
import { TextureError } from "../../Exception/TextureError";
|
||||
import { Companion } from "../Companion/Companion";
|
||||
import type { GameScene } from "../Game/GameScene";
|
||||
import { DEPTH_INGAME_TEXT_INDEX } from "../Game/DepthIndexes";
|
||||
import { waScaleManager } from "../Services/WaScaleManager";
|
||||
import type OutlinePipelinePlugin from "phaser3-rex-plugins/plugins/outlinepipeline-plugin.js";
|
||||
|
||||
const playerNameY = - 25;
|
||||
const playerNameY = -25;
|
||||
|
||||
interface AnimationData {
|
||||
key: string;
|
||||
frameRate: number;
|
||||
repeat: number;
|
||||
frameModel: string; //todo use an enum
|
||||
frames : number[]
|
||||
frames: number[];
|
||||
}
|
||||
|
||||
const interactiveRadius = 35;
|
||||
|
||||
export abstract class Character extends Container {
|
||||
private bubble: SpeechBubble|null = null;
|
||||
private bubble: SpeechBubble | null = null;
|
||||
private readonly playerName: Text;
|
||||
public PlayerValue: string;
|
||||
public sprites: Map<string, Sprite>;
|
||||
|
@ -32,35 +32,41 @@ export abstract class Character extends Container {
|
|||
private invisible: boolean;
|
||||
public companion?: Companion;
|
||||
private emote: Phaser.GameObjects.Text | null = null;
|
||||
private emoteTween: Phaser.Tweens.Tween|null = null;
|
||||
private emoteTween: Phaser.Tweens.Tween | null = null;
|
||||
scene: GameScene;
|
||||
|
||||
constructor(scene: GameScene,
|
||||
x: number,
|
||||
y: number,
|
||||
texturesPromise: Promise<string[]>,
|
||||
name: string,
|
||||
direction: PlayerAnimationDirections,
|
||||
moving: boolean,
|
||||
frame: string | number,
|
||||
isClickable: boolean,
|
||||
companion: string|null,
|
||||
companionTexturePromise?: Promise<string>
|
||||
constructor(
|
||||
scene: GameScene,
|
||||
x: number,
|
||||
y: number,
|
||||
texturesPromise: Promise<string[]>,
|
||||
name: string,
|
||||
direction: PlayerAnimationDirections,
|
||||
moving: boolean,
|
||||
frame: string | number,
|
||||
isClickable: boolean,
|
||||
companion: string | null,
|
||||
companionTexturePromise?: Promise<string>
|
||||
) {
|
||||
super(scene, x, y/*, texture, frame*/);
|
||||
super(scene, x, y /*, texture, frame*/);
|
||||
this.scene = scene;
|
||||
this.PlayerValue = name;
|
||||
this.invisible = true
|
||||
this.invisible = true;
|
||||
|
||||
this.sprites = new Map<string, Sprite>();
|
||||
|
||||
//textures are inside a Promise in case they need to be lazyloaded before use.
|
||||
texturesPromise.then((textures) => {
|
||||
this.addTextures(textures, frame);
|
||||
this.invisible = false
|
||||
})
|
||||
this.invisible = false;
|
||||
});
|
||||
|
||||
this.playerName = new Text(scene, 0, playerNameY, name, {fontFamily: '"Press Start 2P"', fontSize: '8px', strokeThickness: 2, stroke: "gray"});
|
||||
this.playerName = new Text(scene, 0, playerNameY, name, {
|
||||
fontFamily: '"Press Start 2P"',
|
||||
fontSize: "8px",
|
||||
strokeThickness: 2,
|
||||
stroke: "gray",
|
||||
});
|
||||
this.playerName.setOrigin(0.5).setDepth(DEPTH_INGAME_TEXT_INDEX);
|
||||
this.add(this.playerName);
|
||||
|
||||
|
@ -71,18 +77,17 @@ export abstract class Character extends Container {
|
|||
useHandCursor: true,
|
||||
});
|
||||
|
||||
this.on('pointerover',() => {
|
||||
this.on("pointerover", () => {
|
||||
this.getOutlinePlugin()?.add(this.playerName, {
|
||||
thickness: 2,
|
||||
outlineColor: 0xffff00
|
||||
outlineColor: 0xffff00,
|
||||
});
|
||||
this.scene.markDirty();
|
||||
});
|
||||
this.on('pointerout',() => {
|
||||
this.on("pointerout", () => {
|
||||
this.getOutlinePlugin()?.remove(this.playerName);
|
||||
this.scene.markDirty();
|
||||
})
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
scene.add.existing(this);
|
||||
|
@ -97,38 +102,38 @@ export abstract class Character extends Container {
|
|||
|
||||
this.playAnimation(direction, moving);
|
||||
|
||||
if (typeof companion === 'string') {
|
||||
if (typeof companion === "string") {
|
||||
this.addCompanion(companion, companionTexturePromise);
|
||||
}
|
||||
}
|
||||
|
||||
private getOutlinePlugin(): OutlinePipelinePlugin|undefined {
|
||||
return this.scene.plugins.get('rexOutlinePipeline') as unknown as OutlinePipelinePlugin|undefined;
|
||||
private getOutlinePlugin(): OutlinePipelinePlugin | undefined {
|
||||
return this.scene.plugins.get("rexOutlinePipeline") as unknown as OutlinePipelinePlugin | undefined;
|
||||
}
|
||||
|
||||
public addCompanion(name: string, texturePromise?: Promise<string>): void {
|
||||
if (typeof texturePromise !== 'undefined') {
|
||||
if (typeof texturePromise !== "undefined") {
|
||||
this.companion = new Companion(this.scene, this.x, this.y, name, texturePromise);
|
||||
}
|
||||
}
|
||||
|
||||
public addTextures(textures: string[], frame?: string | number): void {
|
||||
for (const texture of textures) {
|
||||
if(this.scene && !this.scene.textures.exists(texture)){
|
||||
throw new TextureError('texture not found');
|
||||
if (this.scene && !this.scene.textures.exists(texture)) {
|
||||
throw new TextureError("texture not found");
|
||||
}
|
||||
const sprite = new Sprite(this.scene, 0, 0, texture, frame);
|
||||
this.add(sprite);
|
||||
this.getPlayerAnimations(texture).forEach(d => {
|
||||
this.getPlayerAnimations(texture).forEach((d) => {
|
||||
this.scene.anims.create({
|
||||
key: d.key,
|
||||
frames: this.scene.anims.generateFrameNumbers(d.frameModel, {frames: d.frames}),
|
||||
frames: this.scene.anims.generateFrameNumbers(d.frameModel, { frames: d.frames }),
|
||||
frameRate: d.frameRate,
|
||||
repeat: d.repeat
|
||||
repeat: d.repeat,
|
||||
});
|
||||
})
|
||||
});
|
||||
// Needed, otherwise, animations are not handled correctly.
|
||||
if(this.scene) {
|
||||
if (this.scene) {
|
||||
this.scene.sys.updateList.add(sprite);
|
||||
}
|
||||
this.sprites.set(texture, sprite);
|
||||
|
@ -136,68 +141,77 @@ export abstract class Character extends Container {
|
|||
}
|
||||
|
||||
private getPlayerAnimations(name: string): AnimationData[] {
|
||||
return [{
|
||||
key: `${name}-${PlayerAnimationDirections.Down}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [0, 1, 2, 1],
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationDirections.Left}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [3, 4, 5, 4],
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationDirections.Right}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [6, 7, 8, 7],
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationDirections.Up}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [9, 10, 11, 10],
|
||||
frameRate: 10,
|
||||
repeat: -1
|
||||
},{
|
||||
key: `${name}-${PlayerAnimationDirections.Down}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [1],
|
||||
frameRate: 10,
|
||||
repeat: 1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationDirections.Left}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [4],
|
||||
frameRate: 10,
|
||||
repeat: 1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationDirections.Right}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [7],
|
||||
frameRate: 10,
|
||||
repeat: 1
|
||||
}, {
|
||||
key: `${name}-${PlayerAnimationDirections.Up}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [10],
|
||||
frameRate: 10,
|
||||
repeat: 1
|
||||
}];
|
||||
return [
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Down}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [0, 1, 2, 1],
|
||||
frameRate: 10,
|
||||
repeat: -1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Left}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [3, 4, 5, 4],
|
||||
frameRate: 10,
|
||||
repeat: -1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Right}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [6, 7, 8, 7],
|
||||
frameRate: 10,
|
||||
repeat: -1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Up}-${PlayerAnimationTypes.Walk}`,
|
||||
frameModel: name,
|
||||
frames: [9, 10, 11, 10],
|
||||
frameRate: 10,
|
||||
repeat: -1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Down}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [1],
|
||||
frameRate: 10,
|
||||
repeat: 1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Left}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [4],
|
||||
frameRate: 10,
|
||||
repeat: 1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Right}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [7],
|
||||
frameRate: 10,
|
||||
repeat: 1,
|
||||
},
|
||||
{
|
||||
key: `${name}-${PlayerAnimationDirections.Up}-${PlayerAnimationTypes.Idle}`,
|
||||
frameModel: name,
|
||||
frames: [10],
|
||||
frameRate: 10,
|
||||
repeat: 1,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
protected playAnimation(direction : PlayerAnimationDirections, moving: boolean): void {
|
||||
protected playAnimation(direction: PlayerAnimationDirections, moving: boolean): void {
|
||||
if (this.invisible) return;
|
||||
for (const [texture, sprite] of this.sprites.entries()) {
|
||||
if (!sprite.anims) {
|
||||
console.error('ANIMS IS NOT DEFINED!!!');
|
||||
console.error("ANIMS IS NOT DEFINED!!!");
|
||||
return;
|
||||
}
|
||||
if (moving && (!sprite.anims.currentAnim || sprite.anims.currentAnim.key !== direction)) {
|
||||
sprite.play(texture+'-'+direction+'-'+PlayerAnimationTypes.Walk, true);
|
||||
sprite.play(texture + "-" + direction + "-" + PlayerAnimationTypes.Walk, true);
|
||||
} else if (!moving) {
|
||||
sprite.anims.play(texture + '-' + direction + '-'+PlayerAnimationTypes.Idle, true);
|
||||
sprite.anims.play(texture + "-" + direction + "-" + PlayerAnimationTypes.Idle, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -205,7 +219,7 @@ export abstract class Character extends Container {
|
|||
protected getBody(): Phaser.Physics.Arcade.Body {
|
||||
const body = this.body;
|
||||
if (!(body instanceof Phaser.Physics.Arcade.Body)) {
|
||||
throw new Error('Container does not have arcade body');
|
||||
throw new Error("Container does not have arcade body");
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
@ -216,16 +230,20 @@ export abstract class Character extends Container {
|
|||
body.setVelocity(x, y);
|
||||
|
||||
// up or down animations are prioritized over left and right
|
||||
if (body.velocity.y < 0) { //moving up
|
||||
if (body.velocity.y < 0) {
|
||||
//moving up
|
||||
this.lastDirection = PlayerAnimationDirections.Up;
|
||||
this.playAnimation(PlayerAnimationDirections.Up, true);
|
||||
} else if (body.velocity.y > 0) { //moving down
|
||||
} else if (body.velocity.y > 0) {
|
||||
//moving down
|
||||
this.lastDirection = PlayerAnimationDirections.Down;
|
||||
this.playAnimation(PlayerAnimationDirections.Down, true);
|
||||
} else if (body.velocity.x > 0) { //moving right
|
||||
} else if (body.velocity.x > 0) {
|
||||
//moving right
|
||||
this.lastDirection = PlayerAnimationDirections.Right;
|
||||
this.playAnimation(PlayerAnimationDirections.Right, true);
|
||||
} else if (body.velocity.x < 0) { //moving left
|
||||
} else if (body.velocity.x < 0) {
|
||||
//moving left
|
||||
this.lastDirection = PlayerAnimationDirections.Left;
|
||||
this.playAnimation(PlayerAnimationDirections.Left, true);
|
||||
}
|
||||
|
@ -237,45 +255,42 @@ export abstract class Character extends Container {
|
|||
}
|
||||
}
|
||||
|
||||
stop(){
|
||||
stop() {
|
||||
this.getBody().setVelocity(0, 0);
|
||||
this.playAnimation(this.lastDirection, false);
|
||||
}
|
||||
|
||||
say(text: string) {
|
||||
if (this.bubble) return;
|
||||
this.bubble = new SpeechBubble(this.scene, this, text)
|
||||
this.bubble = new SpeechBubble(this.scene, this, text);
|
||||
setTimeout(() => {
|
||||
if (this.bubble !== null) {
|
||||
this.bubble.destroy();
|
||||
this.bubble = null;
|
||||
}
|
||||
}, 3000)
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
for (const sprite of this.sprites.values()) {
|
||||
if(this.scene) {
|
||||
if (this.scene) {
|
||||
this.scene.sys.updateList.remove(sprite);
|
||||
}
|
||||
}
|
||||
this.list.forEach(objectContaining => objectContaining.destroy())
|
||||
this.list.forEach((objectContaining) => objectContaining.destroy());
|
||||
super.destroy();
|
||||
}
|
||||
|
||||
playEmote(emote: string) {
|
||||
this.cancelPreviousEmote();
|
||||
|
||||
const scalingFactor = waScaleManager.uiScalingFactor * 0.5;
|
||||
const emoteY = -60 - scalingFactor * 10;
|
||||
const scalingFactor = waScaleManager.uiScalingFactor;
|
||||
const emoteY = -60;
|
||||
|
||||
this.playerName.setVisible(false);
|
||||
this.emote = new Text(this.scene, -12, 0, emote, {fontFamily: '"twemoji"', fontSize:'55px'});
|
||||
this.emote = new Text(this.scene, -12, 0, emote, { fontFamily: '"Twemoji Mozilla"', fontSize: "24px" });
|
||||
this.emote.setAlpha(0);
|
||||
this.emote.setScale(0.1 * scalingFactor);
|
||||
this.add(this.emote);
|
||||
// this.scene.sys.updateList.add(this.emote);
|
||||
|
||||
this.createStartTransition(scalingFactor, emoteY);
|
||||
}
|
||||
|
||||
|
@ -287,11 +302,11 @@ export abstract class Character extends Container {
|
|||
alpha: 1,
|
||||
y: emoteY,
|
||||
},
|
||||
ease: 'Power2',
|
||||
ease: "Power2",
|
||||
duration: 500,
|
||||
onComplete: () => {
|
||||
this.startPulseTransition(emoteY, scalingFactor);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -300,7 +315,7 @@ export abstract class Character extends Container {
|
|||
targets: this.emote,
|
||||
props: {
|
||||
y: emoteY * 1.3,
|
||||
scale: scalingFactor * 1.1
|
||||
scale: scalingFactor * 1.1,
|
||||
},
|
||||
duration: 250,
|
||||
yoyo: true,
|
||||
|
@ -308,7 +323,7 @@ export abstract class Character extends Container {
|
|||
completeDelay: 200,
|
||||
onComplete: () => {
|
||||
this.startExitTransition(emoteY);
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -319,11 +334,11 @@ export abstract class Character extends Container {
|
|||
alpha: 0,
|
||||
y: 2 * emoteY,
|
||||
},
|
||||
ease: 'Power2',
|
||||
ease: "Power2",
|
||||
duration: 500,
|
||||
onComplete: () => {
|
||||
this.destroyEmote();
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -331,7 +346,7 @@ export abstract class Character extends Container {
|
|||
if (!this.emote) return;
|
||||
|
||||
this.emoteTween?.remove();
|
||||
this.destroyEmote()
|
||||
this.destroyEmote();
|
||||
}
|
||||
|
||||
private destroyEmote() {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
import {emoteEventStream} from "../../Connexion/EmoteEventStream";
|
||||
import type {GameScene} from "./GameScene";
|
||||
import type {Subscription} from "rxjs";
|
||||
|
||||
export const emotes: string[] = ['❤️', '👏', '✋', '🙏', '👍', '👎'];
|
||||
import { emoteEventStream } from "../../Connexion/EmoteEventStream";
|
||||
import type { GameScene } from "./GameScene";
|
||||
import type { Subscription } from "rxjs";
|
||||
|
||||
export class EmoteManager {
|
||||
private subscription: Subscription;
|
||||
|
@ -10,18 +8,13 @@ export class EmoteManager {
|
|||
constructor(private scene: GameScene) {
|
||||
this.subscription = emoteEventStream.stream.subscribe((event) => {
|
||||
const actor = this.scene.MapPlayersByKey.get(event.userId);
|
||||
if(actor) {
|
||||
if (actor) {
|
||||
actor.playEmote(event.emote);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
getEmotes(): string[] {
|
||||
// TODO: localstorage + management
|
||||
return emotes;
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.subscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1319,9 +1319,9 @@ ${escapedMessage}
|
|||
if (pointer.wasTouch && (pointer.event as TouchEvent).touches.length > 1) {
|
||||
return; //we don't want the menu to open when pinching on a touch screen.
|
||||
}
|
||||
|
||||
this.CurrentPlayer.openOrCloseEmoteMenu( this.emoteManager.getEmotes());
|
||||
})
|
||||
|
||||
this.CurrentPlayer.openOrCloseEmoteMenu();
|
||||
});
|
||||
this.CurrentPlayer.on(requestEmoteEventName, (emoteKey: string) => {
|
||||
this.connection?.emitEmoteEvent(emoteKey);
|
||||
});
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import {PlayerAnimationDirections} from "./Animation";
|
||||
import type {GameScene} from "../Game/GameScene";
|
||||
import {UserInputEvent, UserInputManager} from "../UserInput/UserInputManager";
|
||||
import {Character} from "../Entity/Character";
|
||||
import {userMovingStore} from "../../Stores/GameStore";
|
||||
import {EmoteMenu, EmoteMenuClickEvent} from "../Components/EmoteMenu";
|
||||
import { PlayerAnimationDirections } from "./Animation";
|
||||
import type { GameScene } from "../Game/GameScene";
|
||||
import { UserInputEvent, UserInputManager } from "../UserInput/UserInputManager";
|
||||
import { Character } from "../Entity/Character";
|
||||
import { userMovingStore } from "../../Stores/GameStore";
|
||||
import { EmoteMenu, EmoteMenuClickEvent } from "../Components/EmoteMenu";
|
||||
|
||||
export const hasMovedEventName = "hasMoved";
|
||||
export const requestEmoteEventName = "requestEmote";
|
||||
|
@ -11,7 +11,7 @@ export const requestEmoteEventName = "requestEmote";
|
|||
export class Player extends Character {
|
||||
private previousDirection: string = PlayerAnimationDirections.Down;
|
||||
private wasMoving: boolean = false;
|
||||
private emoteMenu: EmoteMenu|null = null;
|
||||
private emoteMenu: EmoteMenu | null = null;
|
||||
private updateListener: () => void;
|
||||
|
||||
constructor(
|
||||
|
@ -23,7 +23,7 @@ export class Player extends Character {
|
|||
direction: PlayerAnimationDirections,
|
||||
moving: boolean,
|
||||
private userInputManager: UserInputManager,
|
||||
companion: string|null,
|
||||
companion: string | null,
|
||||
companionTexturePromise?: Promise<string>
|
||||
) {
|
||||
super(Scene, x, y, texturesPromise, name, direction, moving, 1, true, companion, companionTexturePromise);
|
||||
|
@ -37,7 +37,7 @@ export class Player extends Character {
|
|||
this.emoteMenu.y = this.y;
|
||||
}
|
||||
};
|
||||
this.scene.events.addListener('postupdate', this.updateListener);
|
||||
this.scene.events.addListener("postupdate", this.updateListener);
|
||||
}
|
||||
|
||||
moveUser(delta: number): void {
|
||||
|
@ -73,14 +73,14 @@ export class Player extends Character {
|
|||
|
||||
if (x !== 0 || y !== 0) {
|
||||
this.move(x, y);
|
||||
this.emit(hasMovedEventName, {moving, direction, x: this.x, y: this.y});
|
||||
this.emit(hasMovedEventName, { moving, direction, x: this.x, y: this.y });
|
||||
} else if (this.wasMoving && moving) {
|
||||
// slow joystick movement
|
||||
this.move(0, 0);
|
||||
this.emit(hasMovedEventName, {moving, direction: this.previousDirection, x: this.x, y: this.y});
|
||||
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y });
|
||||
} else if (this.wasMoving && !moving) {
|
||||
this.stop();
|
||||
this.emit(hasMovedEventName, {moving, direction: this.previousDirection, x: this.x, y: this.y});
|
||||
this.emit(hasMovedEventName, { moving, direction: this.previousDirection, x: this.x, y: this.y });
|
||||
}
|
||||
|
||||
if (direction !== null) {
|
||||
|
@ -94,17 +94,23 @@ export class Player extends Character {
|
|||
return this.wasMoving;
|
||||
}
|
||||
|
||||
openOrCloseEmoteMenu(emotes:string[]) {
|
||||
if(this.emoteMenu) {
|
||||
openOrCloseEmoteMenu() {
|
||||
if (!this.emoteMenu) {
|
||||
this.emoteMenu = new EmoteMenu(this.scene, this.x, this.y);
|
||||
}
|
||||
|
||||
if (this.emoteMenu.isOpen()) {
|
||||
this.closeEmoteMenu();
|
||||
} else {
|
||||
this.openEmoteMenu(emotes);
|
||||
this.openEmoteMenu();
|
||||
}
|
||||
}
|
||||
|
||||
openEmoteMenu(emotes:string[]): void {
|
||||
openEmoteMenu(): void {
|
||||
this.cancelPreviousEmote();
|
||||
this.emoteMenu = new EmoteMenu(this.scene, this.x, this.y, emotes)
|
||||
if (!this.emoteMenu) return;
|
||||
this.userInputManager.disableControls();
|
||||
this.emoteMenu.openPicker();
|
||||
this.emoteMenu.on(EmoteMenuClickEvent, (emote: string) => {
|
||||
this.closeEmoteMenu();
|
||||
this.emit(requestEmoteEventName, emote);
|
||||
|
@ -113,13 +119,13 @@ export class Player extends Character {
|
|||
}
|
||||
|
||||
closeEmoteMenu(): void {
|
||||
this.userInputManager.restoreControls();
|
||||
if (!this.emoteMenu) return;
|
||||
this.emoteMenu.destroy();
|
||||
this.emoteMenu = null;
|
||||
this.emoteMenu.closePicker();
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.scene.events.removeListener('postupdate', this.updateListener);
|
||||
this.scene.events.removeListener("postupdate", this.updateListener);
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue