diff --git a/front/dist/.gitignore b/front/dist/.gitignore new file mode 100644 index 00000000..64233a9e --- /dev/null +++ b/front/dist/.gitignore @@ -0,0 +1 @@ +index.html \ No newline at end of file diff --git a/front/src/Phaser/Entity/PlayerTextures.ts b/front/src/Phaser/Entity/PlayerTextures.ts index 7d10cc1a..d0542d6a 100644 --- a/front/src/Phaser/Entity/PlayerTextures.ts +++ b/front/src/Phaser/Entity/PlayerTextures.ts @@ -6,7 +6,8 @@ export interface BodyResourceDescriptionListInterface { export interface BodyResourceDescriptionInterface { name: string, - img: string + img: string, + level?: number } export const PLAYER_RESOURCES: BodyResourceDescriptionListInterface = { diff --git a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts index 776d1f5c..78b66c10 100644 --- a/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts +++ b/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts @@ -23,21 +23,26 @@ export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptio }); return returnArray; } -export const loadCustomTexture = (load: LoaderPlugin, texture: CharacterTexture) => { + +export const loadCustomTexture = (loaderPlugin: LoaderPlugin, texture: CharacterTexture) : Promise => { const name = 'customCharacterTexture'+texture.id; - load.spritesheet(name,texture.url,{frameWidth: 32, frameHeight: 32}); - return name; + const playerResourceDescriptor: BodyResourceDescriptionInterface = {name, img: texture.url, level: texture.level} + return createLoadingPromise(loaderPlugin, playerResourceDescriptor); } -export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturePlugin: TextureManager, texturekeys:Array): Promise => { - const promisesList:Promise[] = []; +export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturekeys:Array): Promise => { + const promisesList:Promise[] = []; texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => { - const playerResourceDescriptor = getRessourceDescriptor(textureKey); - if(!texturePlugin.exists(playerResourceDescriptor.name)) { - console.log('Loading '+playerResourceDescriptor.name) - promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor)); + try { + //TODO refactor + const playerResourceDescriptor = getRessourceDescriptor(textureKey); + if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) { + promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor)); + } + }catch (err){ + console.error(err); } - }) + }); let returnPromise:Promise>; if (promisesList.length > 0) { loadPlugin.start(); @@ -66,8 +71,14 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio } const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface) => { - return new Promise((res, rej) => { - loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {frameWidth: 32, frameHeight: 32}); - loadPlugin.once('filecomplete-spritesheet-'+playerResourceDescriptor.name, () => res()); + return new Promise((res) => { + if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) { + return res(playerResourceDescriptor); + } + loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, { + frameWidth: 32, + frameHeight: 32 + }); + loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor)); }); } \ No newline at end of file diff --git a/front/src/Phaser/Game/GameScene.ts b/front/src/Phaser/Game/GameScene.ts index 8e089de7..405fcb85 100644 --- a/front/src/Phaser/Game/GameScene.ts +++ b/front/src/Phaser/Game/GameScene.ts @@ -30,7 +30,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer"; import {Queue} from 'queue-typescript'; import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer"; import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene"; -import {lazyLoadPlayerCharacterTextures} from "../Entity/PlayerTexturesLoadingManager"; +import {lazyLoadPlayerCharacterTextures, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager"; import { CenterListener, layoutManager, @@ -67,6 +67,8 @@ import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCha import {TextureError} from "../../Exception/TextureError"; import {addLoader} from "../Components/Loader"; import {ErrorSceneName} from "../Reconnecting/ErrorScene"; +import {localUserStore} from "../../Connexion/LocalUserStore"; +import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; export interface GameSceneInitInterface { initPosition: PointInterface|null, @@ -183,6 +185,14 @@ export class GameScene extends ResizableScene implements CenterListener { preload(): void { addLoader(this); + const localUser = localUserStore.getLocalUser(); + const textures = localUser?.textures; + if (textures) { + for (const texture of textures) { + loadCustomTexture(this.load, texture); + } + } + this.load.image(openChatIconName, 'resources/objects/talk.png'); this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => { this.scene.start(ErrorSceneName, { @@ -873,7 +883,7 @@ export class GameScene extends ResizableScene implements CenterListener { createCurrentPlayer(){ //TODO create animation moving between exit and start - const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, this.characterLayers); + const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.characterLayers); try { this.CurrentPlayer = new Player( this, @@ -1067,7 +1077,7 @@ export class GameScene extends ResizableScene implements CenterListener { return; } - const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, addPlayerData.characterLayers); + const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, addPlayerData.characterLayers); const player = new RemotePlayer( addPlayerData.userId, this, diff --git a/front/src/Phaser/Login/AbstractCharacterScene.ts b/front/src/Phaser/Login/AbstractCharacterScene.ts new file mode 100644 index 00000000..dfc98539 --- /dev/null +++ b/front/src/Phaser/Login/AbstractCharacterScene.ts @@ -0,0 +1,41 @@ +import {ResizableScene} from "./ResizableScene"; +import {localUserStore} from "../../Connexion/LocalUserStore"; +import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; +import {loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager"; +import {CharacterTexture} from "../../Connexion/LocalUser"; + +export abstract class AbstractCharacterScene extends ResizableScene { + + loadCustomSceneSelectCharacters() : Promise { + const textures = this.getTextures(); + const promises : Promise[] = []; + if (textures) { + for (const texture of textures) { + if (texture.level === -1) { + continue; + } + promises.push(loadCustomTexture(this.load, texture)); + } + } + return Promise.all(promises) + } + + loadSelectSceneCharacters() : Promise { + const textures = this.getTextures(); + const promises: Promise[] = []; + if (textures) { + for (const texture of textures) { + if (texture.level !== -1) { + continue; + } + promises.push(loadCustomTexture(this.load, texture)); + } + } + return Promise.all(promises) + } + + private getTextures() : CharacterTexture[]|undefined{ + const localUser = localUserStore.getLocalUser(); + return localUser?.textures; + } +} \ No newline at end of file diff --git a/front/src/Phaser/Login/CustomizeScene.ts b/front/src/Phaser/Login/CustomizeScene.ts index c6364ef6..4f5b2860 100644 --- a/front/src/Phaser/Login/CustomizeScene.ts +++ b/front/src/Phaser/Login/CustomizeScene.ts @@ -10,6 +10,7 @@ import {ResizableScene} from "./ResizableScene"; import {localUserStore} from "../../Connexion/LocalUserStore"; import {addLoader} from "../Components/Loader"; import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; +import {AbstractCharacterScene} from "./AbstractCharacterScene"; export const CustomizeSceneName = "CustomizeScene"; @@ -20,7 +21,7 @@ enum CustomizeTextures{ arrowUp = "arrow_up", } -export class CustomizeScene extends ResizableScene { +export class CustomizeScene extends AbstractCharacterScene { private textField!: TextField; private enterField!: TextField; @@ -48,29 +49,21 @@ export class CustomizeScene extends ResizableScene { preload() { addLoader(this); + + this.layers = loadAllLayers(this.load); + this.loadCustomSceneSelectCharacters().then((bodyResourceDescriptions) => { + bodyResourceDescriptions.forEach((bodyResourceDescription) => { + if(!bodyResourceDescription.level){ + throw 'Texture level is null'; + } + this.layers[bodyResourceDescription.level].unshift(bodyResourceDescription); + }); + }); + this.load.image(CustomizeTextures.arrowRight, "resources/objects/arrow_right.png"); this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png"); this.load.image(CustomizeTextures.arrowUp, "resources/objects/arrow_up.png"); this.load.bitmapFont(CustomizeTextures.mainFont, 'resources/fonts/arcade.png', 'resources/fonts/arcade.xml'); - - this.layers = loadAllLayers(this.load); - - const localUser = localUserStore.getLocalUser(); - - const textures = localUser?.textures; - if (textures) { - for (const texture of textures) { - if(texture.level === -1){ - continue; - } - loadCustomTexture(this.load, texture); - const name = 'customCharacterTexture'+texture.id; - this.layers[texture.level].unshift({ - name, - img: texture.url - }); - } - } } create() { diff --git a/front/src/Phaser/Login/SelectCharacterScene.ts b/front/src/Phaser/Login/SelectCharacterScene.ts index 25af61c6..905c9ae4 100644 --- a/front/src/Phaser/Login/SelectCharacterScene.ts +++ b/front/src/Phaser/Login/SelectCharacterScene.ts @@ -9,6 +9,7 @@ import {localUserStore} from "../../Connexion/LocalUserStore"; import {loadAllDefaultModels, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager"; import {addLoader} from "../Components/Loader"; import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; +import {AbstractCharacterScene} from "./AbstractCharacterScene"; //todo: put this constants in a dedicated file @@ -21,7 +22,7 @@ enum LoginTextures { customizeButtonSelected = "customize_button_selected" } -export class SelectCharacterScene extends ResizableScene { +export class SelectCharacterScene extends AbstractCharacterScene { private readonly nbCharactersPerRow = 6; private textField!: TextField; private pressReturnField!: TextField; @@ -44,6 +45,13 @@ export class SelectCharacterScene extends ResizableScene { preload() { addLoader(this); + + this.loadSelectSceneCharacters().then((bodyResourceDescriptions) => { + bodyResourceDescriptions.forEach((bodyResourceDescription) => { + this.playerModels.push(bodyResourceDescription); + }); + }) + this.load.image(LoginTextures.playButton, "resources/objects/play_button.png"); this.load.image(LoginTextures.icon, "resources/logos/tcm_full.png"); // Note: arcade.png from the Phaser 3 examples at: https://github.com/photonstorm/phaser3-examples/tree/master/public/assets/fonts/bitmap @@ -51,18 +59,6 @@ export class SelectCharacterScene extends ResizableScene { this.playerModels = loadAllDefaultModels(this.load); this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png'); this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.png'); - - const localUser = localUserStore.getLocalUser(); - const textures = localUser?.textures; - if (textures) { - for (const texture of textures) { - if(texture.level !== -1){ - continue; - } - const name = loadCustomTexture(this.load, texture); - this.playerModels.push({name: name, img: texture.url}); - } - } } create() {