4. 用雪碧图创建精灵

1,607 阅读4分钟

前面说过,创建精灵主要有三种方法:

  • 用一个单图像文件创建
  • 用一个雪碧图来创建
  • 从一个纹理贴图集中创建(纹理贴图集就是用 JSON 定义了图像大小和位置的雪碧图)

我们已经学会了如何用单图像文件创建精灵,接下来看看后两种创建精灵的方式。

一、用一个雪碧图来创建

以下是我们将要用到的雪碧图:

tileset.png

Pixi 可以创建一个矩形区域并设置矩形区域的大小和位置,就可以去捕获雪碧图中的某个子图像。

1. 实例:捕获雪碧图中的火箭,并将它显示出来

let app = new PIXI.Application({
    width: 256,
    height: 256,
    antialias: true,
    transparent: false,
    resolution: 1
});

document.body.appendChild(app.view);

PIXI.loader
    .add("images/tileset.png")
    .load(setup);

function setup() {

    let texture = PIXI.utils.TextureCache["images/tileset.png"]
    
    // 创建一个矩形对象,前两个参数定义坐标位置,后两个参数定义宽高
    let rectangle = new PIXI.Rectangle(96, 64, 32, 32)
    
    // Pixi 的纹理中有一个 frame 属性,它可以被设置成任何的 Rectangle 对象,frame 将纹理映射到 Rectangle 的维度
    texture.frame = rectangle

    let rocket = new PIXI.Sprite(texture);
    rocket.position.set(100, 100)

    app.stage.addChild(rocket);
}

效果图:

image.png

二、从一个纹理贴图集中创建

一个纹理贴图集就是一个 JSON 数据文件,它包含了雪碧图的子图像的大小和位置。如果你使用了纹理贴图集,那么想要显示一个子图像只需要知道它的名字就行了。

如果你想要改变纹理贴图集的排版,或增加图片,或修改图片大小,或删除图片,只需要修改那个 JSON 数据文件就行了,你的游戏会自动给程序内的所有数据应用新的纹理贴图集,也就没必要去代码中修改。

1. Texture Packer 软件

Pixi 兼容著名软件 Texture Packer 输出的标准纹理贴图集格式。

如果使用的是免费版,Texture Packer 需要做如下配置,它就可以正常输出你的纹理贴图集:

image.png

将这个 项目仓库 clone 到本地,里面有所有会用到的资源。

找到以下几个图片,并把它们拉到 Texture Packer 中:

11.png

点击 Publish 保存生成的文件,你会得到一个 json 文件和一个 png 文件。

"blob.png":
{
    "frame": {"x":55,"y":2,"w":32,"h":24},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":32,"h":24},
    "sourceSize": {"w":32,"h":24},
    "pivot": {"x":0.5,"y":0.5}
},

以上是 json 中的一段,描述了 blob.png 的信息。这些单独的子图像被叫做 ,有了这些数据你就不用去记每一个图片的大小和位置了,只要确定精灵的 帧 ID 即可。帧 ID 就是那些图片的原始名称,比如上面的 blob.png

使用纹理贴图集的巨大优势之一就是你可以很轻易的给每一个图像增加两个像素的内边距。Texture Packer 默认这么做。这对于保护图像的 出血(译者:出血是排版和图片处理方面的专有名词,指在主要内容周围留空以便印刷或裁切)来说很重要。出血对于防止两个图片相邻而相互影响来说很重要。这种情况往往发生于你的 GPU 渲染某些图片的时候。把边上的一两个像素加上去还是不要?这对于每一个 GPU 来说都有不同的做法。所以对每一个图像空出一两个像素对于显示来说是最好的兼容。

(注意:如果你真的在每个图像的周围留了两个像素的出血,你必须时时刻刻注意 Pixi 显示时候“丢了一个像素”的情况。尝试着去改变纹理的规模模式来重新计算它。texture.baseTexture.scaleMode = PIXI.SCALE_MODES.NEAREST;,这往往发生于你的 GPU 浮点运算凑整失败的时候。)

2. 加载纹理贴图集

PIXI.loader
  .add("images/xxx.json")
  .load(setup)

如果是用 Texture Packer 生成的 JSON,PIXI.loader 会自动读取数据,并对每一个帧创建纹理。

3. 从已经加载的纹理贴图集中创建精灵

两种方式:

  1. 使用 PIXI.utils.TextureCache:
let texture = PIXI.utils.TextureCache["frameId.png"],
    sprite = new Sprite(texture);
  1. 如果是使用 loader 来加载纹理贴图集,使用 loaderresources
let sprite = new Sprite(
  PIXI.loader.resources["images/xxx.json"].textures["frameId.png"]
);

4. 实例:创建地牢、英雄、怪物、宝箱、门

效果:

image.png

代码: