workadventure/front/src/Phaser/Entity/PlayerTexturesLoadingManager.ts

124 lines
5 KiB
TypeScript
Raw Normal View History

import LoaderPlugin = Phaser.Loader.LoaderPlugin;
2021-06-29 18:39:43 +02:00
import type { CharacterTexture } from "../../Connexion/LocalUser";
import { BodyResourceDescriptionInterface, LAYERS, PLAYER_RESOURCES } from "./PlayerTextures";
export interface FrameConfig {
2021-06-29 18:39:43 +02:00
frameWidth: number;
frameHeight: number;
}
export const loadAllLayers = (load: LoaderPlugin): BodyResourceDescriptionInterface[][] => {
2021-06-29 18:39:43 +02:00
const returnArray: BodyResourceDescriptionInterface[][] = [];
LAYERS.forEach((layer) => {
const layerArray: BodyResourceDescriptionInterface[] = [];
Object.values(layer).forEach((textureDescriptor) => {
layerArray.push(textureDescriptor);
2021-06-29 18:39:43 +02:00
load.spritesheet(textureDescriptor.name, textureDescriptor.img, { frameWidth: 32, frameHeight: 32 });
});
returnArray.push(layerArray);
});
return returnArray;
2021-06-29 18:39:43 +02:00
};
export const loadAllDefaultModels = (load: LoaderPlugin): BodyResourceDescriptionInterface[] => {
const returnArray = Object.values(PLAYER_RESOURCES);
returnArray.forEach((playerResource: BodyResourceDescriptionInterface) => {
2021-06-29 18:39:43 +02:00
load.spritesheet(playerResource.name, playerResource.img, { frameWidth: 32, frameHeight: 32 });
});
return returnArray;
2021-06-29 18:39:43 +02:00
};
2021-01-26 15:21:23 +01:00
2021-06-29 18:39:43 +02:00
export const loadCustomTexture = (
loaderPlugin: LoaderPlugin,
texture: CharacterTexture
): Promise<BodyResourceDescriptionInterface> => {
const name = "customCharacterTexture" + texture.id;
const playerResourceDescriptor: BodyResourceDescriptionInterface = { name, img: texture.url, level: texture.level };
return createLoadingPromise(loaderPlugin, playerResourceDescriptor, {
frameWidth: 32,
2021-06-29 18:39:43 +02:00
frameHeight: 32,
});
2021-06-29 18:39:43 +02:00
};
2021-06-29 18:39:43 +02:00
export const lazyLoadPlayerCharacterTextures = (
loadPlugin: LoaderPlugin,
texturekeys: Array<string | BodyResourceDescriptionInterface>
): Promise<string[]> => {
const promisesList: Promise<unknown>[] = [];
texturekeys.forEach((textureKey: string | BodyResourceDescriptionInterface) => {
2021-01-24 15:57:47 +01:00
try {
2021-01-26 15:21:23 +01:00
//TODO refactor
2021-01-24 15:57:47 +01:00
const playerResourceDescriptor = getRessourceDescriptor(textureKey);
2021-01-26 15:21:23 +01:00
if (playerResourceDescriptor && !loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
2021-06-29 18:39:43 +02:00
promisesList.push(
createLoadingPromise(loadPlugin, playerResourceDescriptor, {
frameWidth: 32,
frameHeight: 32,
})
);
2021-01-24 15:57:47 +01:00
}
2021-06-29 18:39:43 +02:00
} catch (err) {
2021-01-24 15:57:47 +01:00
console.error(err);
}
2021-01-24 15:57:47 +01:00
});
2021-06-29 18:39:43 +02:00
let returnPromise: Promise<Array<string | BodyResourceDescriptionInterface>>;
if (promisesList.length > 0) {
loadPlugin.start();
returnPromise = Promise.all(promisesList).then(() => texturekeys);
} else {
returnPromise = Promise.resolve(texturekeys);
}
2021-06-29 18:39:43 +02:00
//If the loading fail, we render the default model instead.
return returnPromise
.then((keys) =>
keys.map((key) => {
return typeof key !== "string" ? key.name : key;
})
)
.catch(() => lazyLoadPlayerCharacterTextures(loadPlugin, ["color_22", "eyes_23"]));
};
export const getRessourceDescriptor = (
textureKey: string | BodyResourceDescriptionInterface
): BodyResourceDescriptionInterface => {
if (typeof textureKey !== "string" && textureKey.img) {
return textureKey;
}
2021-06-29 18:39:43 +02:00
const textureName: string = typeof textureKey === "string" ? textureKey : textureKey.name;
const playerResource = PLAYER_RESOURCES[textureName];
if (playerResource !== undefined) return playerResource;
2021-06-29 18:39:43 +02:00
for (let i = 0; i < LAYERS.length; i++) {
const playerResource = LAYERS[i][textureName];
if (playerResource !== undefined) return playerResource;
}
2021-06-29 18:39:43 +02:00
throw "Could not find a data for texture " + textureName;
};
2021-06-29 18:39:43 +02:00
export const createLoadingPromise = (
loadPlugin: LoaderPlugin,
playerResourceDescriptor: BodyResourceDescriptionInterface,
frameConfig: FrameConfig
) => {
return new Promise<BodyResourceDescriptionInterface>((res, rej) => {
2021-01-26 15:21:23 +01:00
if (loadPlugin.textureManager.exists(playerResourceDescriptor.name)) {
2021-01-26 09:16:39 +01:00
return res(playerResourceDescriptor);
}
loadPlugin.spritesheet(playerResourceDescriptor.name, playerResourceDescriptor.img, frameConfig);
2021-06-29 18:39:43 +02:00
const errorCallback = (file: { src: string }) => {
if (file.src !== playerResourceDescriptor.img) return;
console.error("failed loading player resource: ", playerResourceDescriptor);
2021-06-29 18:39:43 +02:00
rej(playerResourceDescriptor);
loadPlugin.off("filecomplete-spritesheet-" + playerResourceDescriptor.name, successCallback);
loadPlugin.off("loaderror", errorCallback);
};
const successCallback = () => {
loadPlugin.off("loaderror", errorCallback);
res(playerResourceDescriptor);
};
loadPlugin.once("filecomplete-spritesheet-" + playerResourceDescriptor.name, successCallback);
loadPlugin.on("loaderror", errorCallback);
});
2021-06-29 18:39:43 +02:00
};