diff --git a/front/src/Components/Menu/MenuIcon.svelte b/front/src/Components/Menu/MenuIcon.svelte index 4b37238f..b54fd542 100644 --- a/front/src/Components/Menu/MenuIcon.svelte +++ b/front/src/Components/Menu/MenuIcon.svelte @@ -3,7 +3,9 @@ import logoTalk from "../images/logo-message-pixel.png" import {menuVisiblilityStore} from "../../Stores/MenuStore"; import {chatVisibilityStore} from "../../Stores/ChatStore"; + import {userWokaPictureStore} from "../../Stores/UserWokaPictureStore"; import {get} from "svelte/store"; + import {onDestroy} from "svelte"; function showMenu(){ menuVisiblilityStore.set(!get(menuVisiblilityStore)) @@ -11,12 +13,22 @@ function showChat(){ chatVisibilityStore.set(true); } + + let heroWokaPictureSrc = logoWA; + + const unsubscribeFromUserWokaPictureStore = userWokaPictureStore.subscribe(playersAvatars => { + heroWokaPictureSrc = playersAvatars.get(-1) ?? logoWA; + }); + + onDestroy(unsubscribeFromUserWokaPictureStore); + +
- open menu + open menu open menu
diff --git a/front/src/Phaser/Entity/Character.ts b/front/src/Phaser/Entity/Character.ts index 06ecf1fb..5113a7a7 100644 --- a/front/src/Phaser/Entity/Character.ts +++ b/front/src/Phaser/Entity/Character.ts @@ -118,15 +118,21 @@ export abstract class Character extends Container { } } - public saveCharacterToTexture(saveAs: string): void { + public async getSnapshot(): Promise { const bounds = this.getBounds(); - const rt = this.scene.make.renderTexture({ x: 300, y: 300, width: bounds.width, height: bounds.height}, true); + const rt = this.scene.make.renderTexture({}, false); for (const sprite of this.sprites.values()) { rt.draw(sprite, sprite.displayWidth * 0.5, sprite.displayHeight * 0.5); } - // P.H. NOTE: Change of avatar will update saved texture. We can then send it again to the backend - rt.saveTexture(saveAs); - rt.destroy(); + // TODO: Any way for this to fail? What fallback? + return new Promise((resolve) => { + rt.snapshot((url) => { + resolve(url as HTMLImageElement); // P.H. NOTE: Exclude Color type + // rt.destroy(); + }, + 'image/png', + 1); + }) } public addCompanion(name: string, texturePromise?: Promise): void { diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 9c8a2d2c..b5027cc4 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -67,11 +67,13 @@ import EVENT_TYPE = Phaser.Scenes.Events; import AnimatedTiles from "phaser-animated-tiles"; import { StartPositionCalculator } from "./StartPositionCalculator"; import { soundManager } from "./SoundManager"; + import { peerStore, screenSharingPeerStore } from "../../Stores/PeerStore"; import { videoFocusStore } from "../../Stores/VideoFocusStore"; import { biggestAvailableAreaStore } from "../../Stores/BiggestAvailableAreaStore"; import { SharedVariablesManager } from "./SharedVariablesManager"; import { playersStore } from "../../Stores/PlayersStore"; +import { userWokaPictureStore } from "../../Stores/UserWokaPictureStore"; import { chatVisibilityStore } from "../../Stores/ChatStore"; import { emoteStore, emoteMenuStore } from "../../Stores/EmoteStore"; import { @@ -79,6 +81,7 @@ import { audioManagerVisibilityStore, audioManagerVolumeStore, } from "../../Stores/AudioManagerStore"; + import { PropertyUtils } from "../Map/PropertyUtils"; import Tileset = Phaser.Tilemaps.Tileset; import { userIsAdminStore } from "../../Stores/GameStore"; @@ -665,6 +668,7 @@ export class GameScene extends DirtyScene { this.connection = onConnect.connection; playersStore.connectToRoomConnection(this.connection); + userWokaPictureStore.connectToRoomConnection(this.connection); userIsAdminStore.set(this.connection.hasTag("admin")); @@ -1499,7 +1503,8 @@ ${escapedMessage} this.companion !== null ? lazyLoadCompanionResource(this.load, this.companion) : undefined ); this.CurrentPlayer.once('textures-loaded', () => { - this.savePlayerAvatarPicture(this.CurrentPlayer, 'hero-avatar'); + // TODO: How to be sure we always get hero id? + this.savePlayerWokaPicture(this.CurrentPlayer, -1); }); this.CurrentPlayer.on("pointerdown", (pointer: Phaser.Input.Pointer) => { if (pointer.wasTouch && (pointer.event as TouchEvent).touches.length > 1) { @@ -1528,10 +1533,9 @@ ${escapedMessage} this.createCollisionWithPlayer(); } - private savePlayerAvatarPicture(character: Character, key: string): void { - character.saveCharacterToTexture(key); - console.log(key); - this.add.image(200, 200, key); + private async savePlayerWokaPicture(character: Character, userId: number): Promise { + const htmlImageElement = await character.getSnapshot(); + userWokaPictureStore.setWokaPicture(userId, htmlImageElement.src); } pushPlayerPosition(event: HasPlayerMovedEvent) { @@ -1635,11 +1639,9 @@ ${escapedMessage} break; case "AddPlayerEvent": this.doAddPlayer(event.event); - console.log('ADD PLAYER'); break; case "RemovePlayerEvent": this.doRemovePlayer(event.userId); - console.log('REMOVE PLAYER'); break; case "UserMovedEvent": this.doUpdatePlayerPosition(event.event); @@ -1679,7 +1681,6 @@ ${escapedMessage} */ private doInitUsersPosition(usersPosition: MessageUserPositionInterface[]): void { const currentPlayerId = this.connection?.getUserId(); - console.log(currentPlayerId); this.removeAllRemotePlayers(); // load map usersPosition.forEach((userPosition: MessageUserPositionInterface) => { @@ -1725,7 +1726,7 @@ ${escapedMessage} addPlayerData.companion !== null ? lazyLoadCompanionResource(this.load, addPlayerData.companion) : undefined ); player.once('textures-loaded', () => { - this.savePlayerAvatarPicture(player, `${addPlayerData.userId}-player-avatar`); + this.savePlayerWokaPicture(player, addPlayerData.userId); }); this.MapPlayers.add(player); this.MapPlayersByKey.set(player.userId, player); diff --git a/front/src/Stores/UserWokaPictureStore.ts b/front/src/Stores/UserWokaPictureStore.ts new file mode 100644 index 00000000..de3f759a --- /dev/null +++ b/front/src/Stores/UserWokaPictureStore.ts @@ -0,0 +1,34 @@ +import { writable } from "svelte/store"; +import type { RoomConnection } from "../Connexion/RoomConnection"; + +/** + * A store that contains the players avatars pictures + */ +function createUserWokaPictureStore() { + let players = new Map(); + + const { subscribe, update } = writable(players); + + return { + subscribe, + connectToRoomConnection: (roomConnection: RoomConnection) => { + roomConnection.onUserLeft((userId) => { + update((users) => { + users.delete(userId); + return users; + }); + }); + }, + setWokaPicture(userId: number, url: string) { + update((users) => { + users.set(userId, url); + return users; + }); + }, + getWokaPictureById(userId: number): string | undefined { + return players.get(userId); + }, + }; +} + +export const userWokaPictureStore = createUserWokaPictureStore();