加载骨架数据

在应用程序中实现Spine动画的第一步是加载从Spine导出的纹理图集和骨架数据。

纹理图集

Spine可以打包纹理图集,使渲染骨架更高效。还可以用其他工具以Spine图集格式打包纹理图集,如使用"libgdx"图集格式的Texture Packer Pro。Spine运行时加载图集使用:

TextureLoader textureLoader = ...
Atlas atlas = new Atlas("myAtlas.atlas", textureLoader);

创建图集会解析图集文本文件,该文件包含区域在图集页图片中的位置信息。还会加载每个图集页的图片文件。

TextureLoader

加载图片要视具体游戏工具包,TextureLoader用于创建和处理图片。具体游戏工具包的运行时有一个相应的TextureLoader。在使用通用运行时时,需要写自己的TextureLoader,有两种方法:

void load (AtlasPage page, String path)
void unload (Object rendererObject)

load方法使用路径加载一张图片并在AtlasPage上设置rendererObject字段。unload方法用于处理之前加载的图片。例如,这里Texture是一个游戏工具包类型:

void load (AtlasPage page, String path) {
   Texture texture = GameToolkit.loadTexture(path);
   page.rendererObject = texture;
}

void unload (Object rendererObject) {
   Texture texture = (Texture)rendererObject;
   texture.dispose();
}

AtlasPage上的rendererObject渲染代码使用。

JSON和二进制数据

加载JSON或二进制骨架数据使用SkeletonJsonSkeletonBinary。JSON是人类可读的,但是文件较大,解析慢。二进制很小很快,但是人类不可读。SkeletonJson和SkeletonBinary都有一个readSkeletonData方法,其返回一个SkeletonData

创建SkeletonJson或SkeletonBinary实例需要指定一个AttachmentLoader,它包含返回新附件实例的方法。AttachmentLoader提供了一个加载时自定义附件的方式,如设置附件的图集区域以便稍后渲染。这个很常用,所以Spine运行时自带有一个功能完全相同的AtlasAttachmentLoader:

AtlasAttachmentLoader attachmentLoader = new AtlasAttachmentLoader(atlas);
SkeletonJson json = new SkeletonJson(attachmentLoader);
SkeletonData skeletonData = json.readSkeletonData("mySkeleton.json");

AtlasAttachmentLoader使用附件的path字符串来查找纹理图集中的区域,然后将附件的rendererObject字段设置到该区域稍后被渲染代码使用。

AttachmentLoader

高级用户可能不会使用AtlasAttachmentLoader,而是指定自己的AttachmentLoader,每个附件类型都有一个方法:

RegionAttachment newRegionAttachment (Skin skin, String name, String path)
MeshAttachment newMeshAttachment (Skin skin, String name, String path)
BoundingBoxAttachment newBoundingBoxAttachment (Skin skin, String name, String path)
PathAttachment newPathAttachment (Skin skin, String name, String path)

至少应创建和返回相应类型(或子类)的新附件,再被JSON或二进制文件的数据进一步配置。如果方法返回null,附件将被忽略,就像完全不存在数据中。

对于区域和网格附件,可将rendererObject字段设置到任何渲染代码需求的对象,虽然这是可选的。例如,你可能将骨架数据用于非渲染外的用途并且不需要加载任何图片。或者你可能有数千个附件,不可能在加载骨架数据时加载所有图片。这时可推迟加载图片直至稍后知道实际要用哪些附件。

在渲染发生前的某个时间,必须设置rendererObject及一些关于图集区域的属性,如UV、空白剥离区域大小、原始图片尺寸,以及区域是否被纹理打包器旋转90度。有关设置这些属性的例子,可参考所选运行时的AtlasAttachmentLoader源代码。

缩放

在加载骨架数据后,SkeletonJson或SkeletonBinary类可缩放骨骼位置、图片大小及位移:

SkeletonJson json = new SkeletonJson(attachmentLoader);
json.scale = 2;
SkeletonData skeletonData = json.readSkeletonData("mySkeleton.json");

这样可使用不同尺寸绘制骨架,上例中放大了两倍。如果使用与Spine设计骨架时使用的尺寸不同的图片,缩放很有用。例如,如果使用Spine之前使用的图片一半大小的图片时,可使用一个0.5比例。一些游戏包含不同大小的纹理图集,可根据玩家屏幕分辨率选择。

使用loader比例可更改使用的单位,例如,如果一个骨骼的本地位置是50,100,则使用2个比例在加载时将改为100,200。在运行时不使用像素单位比例的话,这很有用。例如,Box2D偏向于使用米,所以可使用0.01个比例来将像素转换成米。

也可通过缩放根骨骼来缩放骨架,不会影响单位:

SkeletonJson json = new SkeletonJson(attachmentLoader);
SkeletonData skeletonData = json.readSkeletonData("mySkeleton.json");
BoneData root = skeletonData.findBone("root");
root.scaleX = 2;
root.scaleY = 2;

在此例中,如果一个骨骼的本地位置是50,100,该位置将保留不变。但在计算该骨骼的世界变换时,该位置将缩放。如果骨架有禁用了继承比例的骨骼时,可能无法如预期工作。

下一节: 应用动画 上一节: 运行时架构