PixiJS编程指南之Assets

442 阅读3分钟

前言

Assets包是旧Loader(PixiJS加载资源包)类的现代替代品。这是一个基于Promise的资源管理解决方案,它可以下载、缓存和解析资源文件。下载可以同时在后台进行,这意味着应用程序启动时间更快,缓存确保你永远不会下载相同的资源两次,可扩展的解析器系统可以轻松地扩展和定制资源加载过程,以满足需求。

1 Promise

Assets严重依赖所有现代浏览器都支持的 JavaScript Promise。使用Assets.load加载资源,Assets.load可接受资源的url,并返回一个 Promise,返回内容则是根据加载资源类型分别处理。在此示例中,我们将加载纹理,然后将其转换为 sprite。

示例

import { Application, Assets, Sprite } from 'pixi.js';

(async () =>
{
    // 创建应用
    const app = new Application();

    // 初始化应用
    await app.init({ background: '#1099bb', resizeTo: window });

    // 将canvas添加到 document body
    document.body.appendChild(app.canvas);

    // 加载纹理
    const texturePromise = Assets.load('https://pixijs.com/assets/bunny.png');

    texturePromise.then((resolvedTexture) =>
    {
        // 创建 Sprite 用于显示纹理对象
        const bunny = Sprite.from(resolvedTexture);

        // 设置Sprite锚点,默认(0,0),几何变换基于锚点
        bunny.anchor.set(0.5);

        // 将其移动至canvas中心
        bunny.x = app.screen.width / 2;
        bunny.y = app.screen.height / 2;

        app.stage.addChild(bunny);
    });
})();

预览图

1.1 识别url

Assets可加载以下资产类型:

  • 纹理(avif, webp, png, jpg, gif)
  • 精灵图集(json)
  • 位图字体(xml, fnt, txt)
  • 网络字体(ttf, woff, woff2)
  • JSON 文件(json)
  • 文本文件(txt)

资源类型可以通过其文件扩展名来识别,例如,pixijs.com/assets/bunn… 会识别出图片格式png,返回结果会被转化为以该图片生成的纹理,如果是文本则会返回对于字符串 JSON 文件在加载后会被解析为 JavaScript 对象 。

注意,Assets.load接受的不必是一个完整的url,也可以是一个相对url,相对于项目根目录,例如:

const texturePromise = Assets.load("../../assets/image.png")。

2 一次加载多个资源

Assets支持一次性加载多个资源:

Assets.load(['pixijs.com/assets/bg_g…', 'pixijs.com/assets/bg_r…']);

返回结果则是对应资源的被转化后的数组。

此外,Assets还支持动态加载资源。它允许你手动将某个资源添加到 PixiJS 的资源管理器中,而不需要立即加载它。这通常用于预先准备一些资源,或者在之后的某个时刻才加载它们。

这可以帮助你构建资源的加载计划,控制何时加载哪些资源。按需加载,而不需要一次性加载所有资源。这对于性能优化非常重要,尤其是在有大量资源的场景中 。

代码示例

import { Application, Assets, Sprite } from 'pixi.js';


const app = new Application();

app.init({ background: '#1099bb', resizeTo: window }).then(() =>
{

    document.body.appendChild(app.canvas);

    // 添加资源
    // 资源别名,后续load可以通过资源别名加载
    Assets.add({ alias: 'flowerTop', src: 'https://pixijs.com/assets/flowerTop.png' });
    Assets.add({ alias: 'eggHead', src: 'https://pixijs.com/assets/eggHead.png' });


    const texturesPromise = Assets.load(['flowerTop', 'eggHead']); // => Promise<{flowerTop: Texture, eggHead: Texture}>

 
    texturesPromise.then((textures) =>
    {

        const flower = Sprite.from(textures.flowerTop);

        flower.anchor.set(0.5);
        flower.x = app.screen.width * 0.25;
        flower.y = app.screen.height / 2;
        app.stage.addChild(flower);

        const egg = Sprite.from(textures.eggHead);

        egg.anchor.set(0.5);
        egg.x = app.screen.width * 0.75;
        egg.y = app.screen.height / 2;
        app.stage.addChild(egg);
    });
});

3 后台加载

PixiJS的Assets允许在后台加载所有资源,如果需要某些资源,可以将它们放在队列的顶部,这样就可以最小化加载时间。如果需要某个资源时,只需要调用Assets.load即可,如果该资源已经在后台记载完毕,那么就会立即返回该资源,如果该资源还没有加载,那么就会强制优先加载这个资源。

代码示例

import { Application, Assets, Sprite } from "pixi.js";

const app = new Application();

app.init({ background: "#1099bb", resizeTo: window }).then(() => {

  document.body.appendChild(app.canvas);

  // 添加资源
  Assets.add({
    alias: "flowerTop",
    src: "https://pixijs.com/assets/flowerTop.png",
  });
  Assets.add({
    alias: "eggHead",
    src: "https://pixijs.com/assets/eggHead.png",
  });

  // 在后台加载资源
  Assets.backgroundLoad(["flowerTop", "eggHead"]);

  Assets.load("eggHead").then((texture) => {
    let isEggHead = true;

    const character = new Sprite(texture);

    character.anchor.set(0.5);
    character.x = app.screen.width / 2;
    character.y = app.screen.height / 2;
    character.eventMode = "static";
    character.cursor = "pointer";

    app.stage.addChild(character);

    character.on("pointertap", async () => {
      isEggHead = !isEggHead;
      // These promise are already resolved in the cache.
      character.texture = await Assets.load(
        isEggHead ? "eggHead" : "flowerTop"
      );
    });
  });
});