Merge pull request #648 from thecodingmachine/customCharacterLadyLoading

Fix custom character lazy loading
This commit is contained in:
grégoire parant 2021-01-26 15:27:46 +01:00 committed by GitHub
commit 86f1099247
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 103 additions and 50 deletions

1
front/dist/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
index.html

View File

@ -6,7 +6,8 @@ export interface BodyResourceDescriptionListInterface {
export interface BodyResourceDescriptionInterface { export interface BodyResourceDescriptionInterface {
name: string, name: string,
img: string img: string,
level?: number
} }
export const PLAYER_RESOURCES: BodyResourceDescriptionListInterface = { export const PLAYER_RESOURCES: BodyResourceDescriptionListInterface = {

View File

@ -23,21 +23,26 @@ export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptio
}); });
return returnArray; return returnArray;
} }
export const loadCustomTexture = (load: LoaderPlugin, texture: CharacterTexture) => {
export const loadCustomTexture = (loaderPlugin: LoaderPlugin, texture: CharacterTexture) : Promise<BodyResourceDescriptionInterface> => {
const name = 'customCharacterTexture'+texture.id; const name = 'customCharacterTexture'+texture.id;
load.spritesheet(name,texture.url,{frameWidth: 32, frameHeight: 32}); const playerResourceDescriptor: BodyResourceDescriptionInterface = {name, img: texture.url, level: texture.level}
return name; return createLoadingPromise(loaderPlugin, playerResourceDescriptor);
} }
export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturePlugin: TextureManager, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => { export const lazyLoadPlayerCharacterTextures = (loadPlugin: LoaderPlugin, texturekeys:Array<string|BodyResourceDescriptionInterface>): Promise<string[]> => {
const promisesList:Promise<void>[] = []; const promisesList:Promise<unknown>[] = [];
texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => { texturekeys.forEach((textureKey: string|BodyResourceDescriptionInterface) => {
const playerResourceDescriptor = getRessourceDescriptor(textureKey); try {
if(!texturePlugin.exists(playerResourceDescriptor.name)) { //TODO refactor
console.log('Loading '+playerResourceDescriptor.name) const playerResourceDescriptor = getRessourceDescriptor(textureKey);
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor)); if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
promisesList.push(createLoadingPromise(loadPlugin, playerResourceDescriptor));
}
}catch (err){
console.error(err);
} }
}) });
let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>; let returnPromise:Promise<Array<string|BodyResourceDescriptionInterface>>;
if (promisesList.length > 0) { if (promisesList.length > 0) {
loadPlugin.start(); loadPlugin.start();
@ -66,8 +71,14 @@ export const getRessourceDescriptor = (textureKey: string|BodyResourceDescriptio
} }
const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface) => { const createLoadingPromise = (loadPlugin: LoaderPlugin, playerResourceDescriptor: BodyResourceDescriptionInterface) => {
return new Promise<void>((res, rej) => { return new Promise<BodyResourceDescriptionInterface>((res) => {
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {frameWidth: 32, frameHeight: 32}); if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
loadPlugin.once('filecomplete-spritesheet-'+playerResourceDescriptor.name, () => res()); return res(playerResourceDescriptor);
}
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, {
frameWidth: 32,
frameHeight: 32
});
loadPlugin.once('filecomplete-spritesheet-' + playerResourceDescriptor.name, () => res(playerResourceDescriptor));
}); });
} }

View File

@ -30,7 +30,7 @@ import {RemotePlayer} from "../Entity/RemotePlayer";
import {Queue} from 'queue-typescript'; import {Queue} from 'queue-typescript';
import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer"; import {SimplePeer, UserSimplePeerInterface} from "../../WebRtc/SimplePeer";
import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene"; import {ReconnectingSceneName} from "../Reconnecting/ReconnectingScene";
import {lazyLoadPlayerCharacterTextures} from "../Entity/PlayerTexturesLoadingManager"; import {lazyLoadPlayerCharacterTextures, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
import { import {
CenterListener, CenterListener,
layoutManager, layoutManager,
@ -67,6 +67,8 @@ import {SelectCharacterScene, SelectCharacterSceneName} from "../Login/SelectCha
import {TextureError} from "../../Exception/TextureError"; import {TextureError} from "../../Exception/TextureError";
import {addLoader} from "../Components/Loader"; import {addLoader} from "../Components/Loader";
import {ErrorSceneName} from "../Reconnecting/ErrorScene"; import {ErrorSceneName} from "../Reconnecting/ErrorScene";
import {localUserStore} from "../../Connexion/LocalUserStore";
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
export interface GameSceneInitInterface { export interface GameSceneInitInterface {
initPosition: PointInterface|null, initPosition: PointInterface|null,
@ -183,6 +185,14 @@ export class GameScene extends ResizableScene implements CenterListener {
preload(): void { preload(): void {
addLoader(this); 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.image(openChatIconName, 'resources/objects/talk.png');
this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => { this.load.on(FILE_LOAD_ERROR, (file: {src: string}) => {
this.scene.start(ErrorSceneName, { this.scene.start(ErrorSceneName, {
@ -873,7 +883,7 @@ export class GameScene extends ResizableScene implements CenterListener {
createCurrentPlayer(){ createCurrentPlayer(){
//TODO create animation moving between exit and start //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 { try {
this.CurrentPlayer = new Player( this.CurrentPlayer = new Player(
this, this,
@ -1067,7 +1077,7 @@ export class GameScene extends ResizableScene implements CenterListener {
return; return;
} }
const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, this.textures, addPlayerData.characterLayers); const texturesPromise = lazyLoadPlayerCharacterTextures(this.load, addPlayerData.characterLayers);
const player = new RemotePlayer( const player = new RemotePlayer(
addPlayerData.userId, addPlayerData.userId,
this, this,

View File

@ -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<BodyResourceDescriptionInterface[]> {
const textures = this.getTextures();
const promises : Promise<BodyResourceDescriptionInterface>[] = [];
if (textures) {
for (const texture of textures) {
if (texture.level === -1) {
continue;
}
promises.push(loadCustomTexture(this.load, texture));
}
}
return Promise.all(promises)
}
loadSelectSceneCharacters() : Promise<BodyResourceDescriptionInterface[]> {
const textures = this.getTextures();
const promises: Promise<BodyResourceDescriptionInterface>[] = [];
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;
}
}

View File

@ -10,6 +10,7 @@ import {ResizableScene} from "./ResizableScene";
import {localUserStore} from "../../Connexion/LocalUserStore"; import {localUserStore} from "../../Connexion/LocalUserStore";
import {addLoader} from "../Components/Loader"; import {addLoader} from "../Components/Loader";
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
import {AbstractCharacterScene} from "./AbstractCharacterScene";
export const CustomizeSceneName = "CustomizeScene"; export const CustomizeSceneName = "CustomizeScene";
@ -20,7 +21,7 @@ enum CustomizeTextures{
arrowUp = "arrow_up", arrowUp = "arrow_up",
} }
export class CustomizeScene extends ResizableScene { export class CustomizeScene extends AbstractCharacterScene {
private textField!: TextField; private textField!: TextField;
private enterField!: TextField; private enterField!: TextField;
@ -48,29 +49,21 @@ export class CustomizeScene extends ResizableScene {
preload() { preload() {
addLoader(this); 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.arrowRight, "resources/objects/arrow_right.png");
this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png"); this.load.image(CustomizeTextures.icon, "resources/logos/tcm_full.png");
this.load.image(CustomizeTextures.arrowUp, "resources/objects/arrow_up.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.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() { create() {

View File

@ -9,6 +9,7 @@ import {localUserStore} from "../../Connexion/LocalUserStore";
import {loadAllDefaultModels, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager"; import {loadAllDefaultModels, loadCustomTexture} from "../Entity/PlayerTexturesLoadingManager";
import {addLoader} from "../Components/Loader"; import {addLoader} from "../Components/Loader";
import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures"; import {BodyResourceDescriptionInterface} from "../Entity/PlayerTextures";
import {AbstractCharacterScene} from "./AbstractCharacterScene";
//todo: put this constants in a dedicated file //todo: put this constants in a dedicated file
@ -21,7 +22,7 @@ enum LoginTextures {
customizeButtonSelected = "customize_button_selected" customizeButtonSelected = "customize_button_selected"
} }
export class SelectCharacterScene extends ResizableScene { export class SelectCharacterScene extends AbstractCharacterScene {
private readonly nbCharactersPerRow = 6; private readonly nbCharactersPerRow = 6;
private textField!: TextField; private textField!: TextField;
private pressReturnField!: TextField; private pressReturnField!: TextField;
@ -44,6 +45,13 @@ export class SelectCharacterScene extends ResizableScene {
preload() { preload() {
addLoader(this); 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.playButton, "resources/objects/play_button.png");
this.load.image(LoginTextures.icon, "resources/logos/tcm_full.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 // 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.playerModels = loadAllDefaultModels(this.load);
this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png'); this.load.image(LoginTextures.customizeButton, 'resources/objects/customize.png');
this.load.image(LoginTextures.customizeButtonSelected, 'resources/objects/customize_selected.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() { create() {