diff --git a/front/src/Phaser/Components/TalkIcon.ts b/front/src/Phaser/Components/TalkIcon.ts new file mode 100644 index 00000000..02fa71fc --- /dev/null +++ b/front/src/Phaser/Components/TalkIcon.ts @@ -0,0 +1,57 @@ +import { Easing } from '../../types'; + +export class TalkIcon extends Phaser.GameObjects.Image { + + private shown: boolean; + private showAnimationTween?: Phaser.Tweens.Tween; + + private defaultPosition: { x: number, y: number }; + private defaultScale: number; + + constructor(scene: Phaser.Scene, x: number, y: number) { + super(scene, x, y, 'iconTalk'); + + this.defaultPosition = { x, y }; + this.defaultScale = 0.15; + + this.shown = false; + this.setAlpha(0); + this.setScale(this.defaultScale); + + this.scene.add.existing(this); + } + + public show(show: boolean = true): void { + if (this.shown === show) { + return; + } + this.showAnimation(show); + } + + private showAnimation(show: boolean = true) { + if (this.showAnimationTween?.isPlaying()) { + return; + } + this.shown = show; + if (show) { + this.y += 50; + this.scale = 0.05; + this.alpha = 0; + } + this.showAnimationTween = this.scene.tweens.add({ + targets: [ this ], + duration: 350, + alpha: show ? 1 : 0, + y: this.defaultPosition.y, + scale: this.defaultScale, + ease: Easing.BackEaseOut, + onComplete: () => { + this.showAnimationTween = undefined; + } + }); + } + + public isShown(): boolean { + return this.shown; + } +} diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index fd264f03..85ba8779 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -17,6 +17,7 @@ import { Unsubscriber, Writable, writable } from "svelte/store"; import { createColorStore } from "../../Stores/OutlineColorStore"; import type { OutlineableInterface } from "../Game/OutlineableInterface"; import type CancelablePromise from "cancelable-promise"; +import { TalkIcon } from '../Components/TalkIcon'; const playerNameY = -25; @@ -33,7 +34,7 @@ const interactiveRadius = 35; export abstract class Character extends Container implements OutlineableInterface { private bubble: SpeechBubble | null = null; private readonly playerNameText: Text; - private readonly iconTalk: Phaser.GameObjects.Image; + private readonly talkIcon: TalkIcon; public playerName: string; public sprites: Map; protected lastDirection: PlayerAnimationDirections = PlayerAnimationDirections.Down; @@ -104,10 +105,8 @@ export abstract class Character extends Container implements OutlineableInterfac }, }); - this.iconTalk = new Phaser.GameObjects.Image(scene, 0, -45, 'iconTalk') - .setScale(0.15) - .setVisible(false); - this.add(this.iconTalk); + this.talkIcon = new TalkIcon(scene, 0, -45); + this.add(this.talkIcon); if (isClickable) { this.setInteractive({ @@ -193,8 +192,8 @@ export abstract class Character extends Container implements OutlineableInterfac }); } - public showIconTalk(show: boolean = true): void { - this.iconTalk.setVisible(show); + public showTalkIcon(show: boolean = true): void { + this.talkIcon.show(show); } public addCompanion(name: string, texturePromise?: Promise): void { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index bf762fec..9ddb5b96 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -647,9 +647,7 @@ export class GameScene extends DirtyScene { for (const [key, videoStream] of peers) { this.volumeStoreUnsubscribers.set(key, videoStream.volumeStore.subscribe((volume) => { if (volume) { - console.log(`${key}: ${volume}`); - this.MapPlayersByKey.get(key)?.showIconTalk(volume > 5); - this.markDirty(); // should be dirty from animation + this.MapPlayersByKey.get(key)?.showTalkIcon(volume > 5); } })); } @@ -663,8 +661,7 @@ export class GameScene extends DirtyScene { if (newPeerNumber > 0) { this.localVolumeStoreUnsubscriber = localVolumeStore.subscribe((volume) => { if (volume) { - this.CurrentPlayer.showIconTalk(volume > 5); - this.markDirty(); // should be dirty from animation + this.CurrentPlayer.showTalkIcon(volume > 5); } }); } else {