PixiJs ———— 精灵加载去缓存

pixi.js v5.2.0 加载精灵的时候会有缓存相关的 warning,每次都两百多条 warning,这谁受得了,花了点时间,各种调试,终于把他们给去掉了,舒服。可能有人会问,直接 google cv 一条龙不就解决了,但是网上关于 pixi.js 的文档是很少的,官方文档看了看,开发论坛看了看,都说用 clearTextureCache 方法,,通过打印发现是在 load 阶段给出的 warning,所以这里没用。先看看比如我一开始的代码,长这样

function loadBaseImgs() {
  const loader = new PIXI.Loader();
  const textures = {};

  loader.add(baseImgArr);

  return new Promise((resolve) => {
    loader.load((loaders, resources) => {
      PIXI.utils.clearTextureCache();
      const lazer = resources.lazer.textures;
      const lazerGreen = lazer['greenPen'];
      const lazerRed = lazer['redPen'];
      const lazerYellow = lazer['yellow'];
      const lazerZise = lazer['zise'];
      textures.lazerGreen = lazerGreen;
      textures.lazerRed = lazerRed;
      textures.lazerYellow = lazerYellow;
      textures.lazerZise = lazerZise;
      resolve(textures);
    });
  })

看起来没毛病,跟 pixi.js 开发者说的解决方案一样,但是在第一次的时候还是打印了很多,warning 内容都是 Texture added to the cache with an id [...] that already had an entry, 这句话告诉我们 map 中已经有了该 id 的键值对,看 pixi.js 的 issue 发现开发者说这个不影响,只是提示而已。感受一下两百多条提示,你就会发现很有必要去掉它,谁知道因为这个会发生什么呢。

warning

很吓人吧,然后跳到给出 warning 的地方

PixiJs ———— 精灵加载去缓存_第1张图片

可以看到这段代码

Texture.addToCache = function addToCache(texture, id) {
  if (id) {
    if (texture.textureCacheIds.indexOf(id) === -1) {
      texture.textureCacheIds.push(id);
    }

    if (_pixi_utils__WEBPACK_IMPORTED_MODULE_1__['TextureCache'][id]) {
      // eslint-disable-next-line no-console
      console.warn(
        'Texture added to the cache with an id [' +
          id +
          '] that already had an entry'
      );
    }

    _pixi_utils__WEBPACK_IMPORTED_MODULE_1__['TextureCache'][id] = texture;
  }
};

从以上代码可以发现,这个 warning 是在 addToCache 的时候触发的,那么再去看看文档关于 PIXI.Loader 的描述吧,可以看到 PIXI 加载精灵集的方式有两种

const loader = PIXI.Loader.shared; // PixiJS exposes a premade instance for you to use.
//or
const loader = new PIXI.Loader(); // you can also create your own if you want

以上第一种是 PixiJS 暴露的一个默认实例,第二种是我们自己 new 的实例,这里我用的是第二种会打印 warning,那么试试第一种方式吧,修改代码为:

function loadBaseImgs() {
  const loader = PIXI.Loader.shared;
  const textures = {};

  loader.add(baseImgArr);

  return new Promise((resolve) => {
    loader.load((loaders, resources) => {
      PIXI.utils.clearTextureCache();
      const lazer = resources.lazer.textures;
      const lazerGreen = lazer['greenPen'];
      const lazerRed = lazer['redPen'];
      const lazerYellow = lazer['yellow'];
      const lazerZise = lazer['zise'];
      textures.lazerGreen = lazerGreen;
      textures.lazerRed = lazerRed;
      textures.lazerYellow = lazerYellow;
      textures.lazerZise = lazerZise;
      resolve(textures);
    });
  })

这下 error 来了

Uncaught (in promise) Error: Cannot add resources while the loader is running.

只能用一个 loader 实例?那么就在添加新的 resource 之前,重置一下 loader 吧

function loadBaseImgs() {
  const loader = PIXI.Loader.shared;
  const textures = {};

  loader.reset();
  loader.add(baseImgArr);

  return new Promise((resolve) => {
    loader.load((loaders, resources) => {
      PIXI.utils.clearTextureCache();
      const lazer = resources.lazer.textures;
      const lazerGreen = lazer['greenPen'];
      const lazerRed = lazer['redPen'];
      const lazerYellow = lazer['yellow'];
      const lazerZise = lazer['zise'];
      textures.lazerGreen = lazerGreen;
      textures.lazerRed = lazerRed;
      textures.lazerYellow = lazerYellow;
      textures.lazerZise = lazerZise;
      resolve(textures);
    });
  })

emmm, 搞定,warning 再见。

等等,这样写虽然解决了问题,但是每次 loader 都会重新加载,每次执行函数也会重新的的去异步加载 resources,这明显不科学,不如把资源添加的环节放到函数外面去,这样就不用每次进来都 add 一下了

const loader = PIXI.Loader.shared;
const textures = {};

loader.add(baseImgArr);
function loadBaseImgs() {
  return new Promise((resolve) => {
    loader.load((loaders, resources) => {
      PIXI.utils.clearTextureCache();
      const lazer = resources.lazer.textures;
      const lazerGreen = lazer['greenPen'];
      const lazerRed = lazer['redPen'];
      const lazerYellow = lazer['yellow'];
      const lazerZise = lazer['zise'];
      textures.lazerGreen = lazerGreen;
      textures.lazerRed = lazerRed;
      textures.lazerYellow = lazerYellow;
      textures.lazerZise = lazerZise;
      resolve(textures);
    });
  })

这样写,每次调用函数减少了 add 环节,但是还是会重复的 load,再改进一些,load 只用于拿数据,处理数据的部分分割出来,由于第一次 load 完毕,已经可以拿到所有的 texture 了,所以可以在这个阶段去把 resources 存起来,以后通过判断有没有这个 resources,决定是否要 load,改进代码如下:

const loader = PIXI.Loader.shared;
const textures = {};
let resInstance = null;

loader.add(baseImgArr);

function loaded(resources, resolve) {
  PIXI.utils.clearTextureCache();
  const lazer = resources.lazer.textures;
  const lazerGreen = lazer['greenPen'];
  const lazerRed = lazer['redPen'];
  const lazerYellow = lazer['yellow'];
  const lazerZise = lazer['zise'];
  textures.lazerGreen = lazerGreen;
  textures.lazerRed = lazerRed;
  textures.lazerYellow = lazerYellow;
  textures.lazerZise = lazerZise;
  resolve(textures);
}
function loadBaseImgs() {
  return new Promise((resolve) => {
    if(resInstance) {
      loaded(resInstance, resolve);
      return;
    }
    loader.load((loaders, resources) => {
      resInstance = resources;
      loaded(resInstance, resolve);
    });
  })

文章同步发布掘金:https://juejin.im/post/5e8b39...

本文作者:Canace

首发链接:https://canace.site/2020/04/0...

版权声明:转载请注明出处

你可能感兴趣的:(前端,javascript,pixi.js,pixijs,webgl)