Начнём с интерфейса загрузчика, который хотим реализовать.
class Application {
run(config) {
// …
this.loader = new Loader(this.app.loader, this.config);
this.loader.preload().then(() => this.start());
}
start() {
}
Для загрузки ресурсов PIXI предоставляет класс PIXI.Loader. Его можно получить из свойства app.
Передадим его первым параметром в конструктор нашего класса Loader. Вторым параметром будет список загружаемых ресурсов.
Создайте класс src/scripts/system/Loader.js:
export class Loader {
constructor(loader, config) {
this.loader = loader;
this.config = config;
this.resources = {};
}
preload() {
return Promise.resolve();
}
}
Все загруженные объекты ресурсов будем добавлять в свойство resources, изначально пустое.
Поскольку список ресурсов уникален для каждой игры, конфигурацию ресурсов нужно определить отдельно от общего кода, то есть вне папки system.
Создадим файл game/Config.js. В нём создадим объект Config, уникальный для каждой конкретной игры:
import { Tools } from "../system/Tools";
export const Config = {
loader: Tools.massiveRequire(require["context"]('./../../sprites/', true, /\.(mp3|png|jpe?g)$/))
};
Зададим список загружаемых ресурсов в свойстве loader.
Для автоматического получения всех ресурсов из заданной папки используем возможности require.context.
Создадим системный класс Tools и реализуем в нём метод massiveRequre:
export class Tools {
static massiveRequire(req) {
const files = [];
req.keys().forEach(key => {
files.push({
key, data: req(key)
});
});
return files;
}
}
Теперь нужно обновить точку входа:
import { Config } from "./game/Config";
import { App } from "./system/App";
App.run(Config);
Теперь можно полностью реализовать preload в классе Loader. Сделаем это в два шага:
- Добавим все ресурсы из конфигурации загрузчика в список загрузки методом
this.loader.add. - Запустим загрузку ресурсов через
this.loader.load.
export class Loader {
// ...
preload() {
for (const asset of this.config.loader) {
let key = asset.key.substr(asset.key.lastIndexOf('/') + 1);
key = key.substring(0, key.indexOf('.'));
if (asset.key.indexOf(".png") !== -1 || asset.key.indexOf(".jpg") !== -1) {
this.loader.add(key, asset.data.default)
}
}
return new Promise(resolve => {
this.loader.load((loader, resources) => {
this.resources = resources;
resolve();
});
});
}
}
Метод load объекта PIXI.Loader принимает callback, вызываемый после завершения загрузки всех ресурсов, когда они становятся доступны для использования.
Callback принимает два параметра: сам загрузчик и загруженные ресурсы. Поместим ресурсы в поле resources класса Loader, которое мы специально оставили для всех загруженных ресурсов.