diff --git a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts index 78b66c10..3dfe8368 100644 --- a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts +++ b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts @@ -62,7 +62,7 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio const textureName:string = typeof textureKey === 'string' ? textureKey : textureKey.name; const playerResource = PLAYER_RESOURCES[textureName]; if (playerResource !== undefined) return playerResource; - + for (let i=0; i<LAYERS.length;i++) { const playerResource = LAYERS[i][textureName]; if (playerResource !== undefined) return playerResource; @@ -81,4 +81,4 @@ const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor }); loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor)); }); -} \ No newline at end of file +} diff --git a/front/src/Phaser/Game/DirtyScene.ts b/front/src/Phaser/Game/DirtyScene.ts new file mode 100644 index 00000000..4b91255f --- /dev/null +++ b/front/src/Phaser/Game/DirtyScene.ts @@ -0,0 +1,52 @@ +import {ResizableScene} from "../Login/ResizableScene"; +import GameObject = Phaser.GameObjects.GameObject; +import Events = Phaser.Scenes.Events; +import AnimationEvents = Phaser.Animations.Events; + +/** + * A scene that can track its dirty/pristine state. + */ +export abstract class DirtyScene extends ResizableScene { + private isAlreadyTracking: boolean = false; + protected dirty:boolean = true; + private objectListChanged:boolean = true; + + /** + * Track all objects added to the scene and adds a callback each time an animation is added. + * Whenever an object is added, removed, or when an animation is played, the dirty state is set to true. + * + * Note: this does not work with animations from sprites inside containers. + */ + protected trackDirtyAnims(): void { + if (this.isAlreadyTracking) { + return; + } + this.isAlreadyTracking = true; + const trackAnimationFunction = this.trackAnimation.bind(this); + this.events.on(Events.ADDED_TO_SCENE, (gameObject: GameObject) => { + this.objectListChanged = true; + gameObject.on(AnimationEvents.ANIMATION_UPDATE, trackAnimationFunction); + }); + + this.events.on(Events.REMOVED_FROM_SCENE, (gameObject: GameObject) => { + this.objectListChanged = true; + gameObject.removeListener(AnimationEvents.ANIMATION_UPDATE, trackAnimationFunction); + }); + + this.events.on(Events.RENDER, () => { + this.objectListChanged = false; + }); + } + + private trackAnimation(): void { + this.objectListChanged = true; + } + + public isDirty(): boolean { + return this.dirty || this.objectListChanged; + } + + public onResize(): void { + this.objectListChanged = true; + } +} diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 672de5e6..6bedf469 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -81,6 +81,9 @@ import DOMElement = Phaser.GameObjects.DOMElement; import {Subscription} from "rxjs"; import {worldFullMessageStream} from "../../Connexion/WorldFullMessageStream"; import { lazyLoadCompanionResource } from "../Companion/CompanionTexturesLoadingManager"; +import RenderTexture = Phaser.GameObjects.RenderTexture; +import Tilemap = Phaser.Tilemaps.Tilemap; +import {DirtyScene} from "./DirtyScene"; export interface GameSceneInitInterface { initPosition: PointInterface|null, @@ -119,7 +122,7 @@ interface DeleteGroupEventInterface { const defaultStartLayerName = 'start'; -export class GameScene extends ResizableScene implements CenterListener { +export class GameScene extends DirtyScene implements CenterListener { Terrains : Array<Phaser.Tilemaps.Tileset>; CurrentPlayer!: CurrentGamerInterface; MapPlayers!: Phaser.Physics.Arcade.Group; @@ -195,6 +198,7 @@ export class GameScene extends ResizableScene implements CenterListener { this.connectionAnswerPromise = new Promise<RoomJoinedMessageInterface>((resolve, reject): void => { this.connectionAnswerPromiseResolve = resolve; }) + } //hook preload scene @@ -354,6 +358,8 @@ export class GameScene extends ResizableScene implements CenterListener { //hook create scene create(): void { + this.trackDirtyAnims(); + gameManager.gameSceneIsCreated(this); urlManager.pushRoomIdToUrl(this.room); this.startLayerName = urlManager.getStartLayerNameFromUrl(); @@ -1187,8 +1193,6 @@ ${escapedMessage} }); } - private dirty:boolean = true; - /** * @param time * @param delta The delta time in ms since the last frame. This is a smoothed and capped value based on the FPS rate. @@ -1202,11 +1206,11 @@ ${escapedMessage} this.dirty = false; mediaManager.setLastUpdateScene(); this.currentTick = time; - if (this.CurrentPlayer.isMoving() === true) { + if (this.CurrentPlayer.isMoving()) { this.dirty = true; } this.CurrentPlayer.moveUser(delta); - if (this.CurrentPlayer.isMoving() === true) { + if (this.CurrentPlayer.isMoving()) { this.dirty = true; this.physics.enableUpdate(); } else { @@ -1413,6 +1417,7 @@ ${escapedMessage} } public onResize(): void { + super.onResize(); this.reposition(); // Send new viewport to server @@ -1512,8 +1517,4 @@ ${escapedMessage} message: 'If you want more information, you may contact us at: workadventure@thecodingmachine.com' }); } - - public isDirty(): boolean { - return this.dirty; - } }