# spine-haxe 运行时文档

> **Licensing**
>
> 将官方的Spine运行时整合到你的应用程序之前, 请仔细阅读 [Spine运行时许可页面](/spine-runtimes-license).

# 简介

spine-haxe运行时包括一个渲染器无关的核心模块, 该模块是一个Spine Runtimes核心API的Haxe实现, 以及以下渲染器实现:

- [Starling](https://lib.haxe.org/p/starling/)
- [HaxeFlixel](https://lib.haxe.org/p/flixel/) (最低支持 5.9.0)

spine-haxe 针对 HTML5 进行过测试, 且渲染功能与当前版本的 [WebGL](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) 兼容. 它支持全部 Spine 功能, 除了预乘(premultiplied) alpha atlases和双色tinting.

## 安装

spine-haxe的核心模块不含任何依赖项.

Starling渲染实现有两个依赖项: openfl和starling:

```plain
haxelib install openfl
haxelib install starling
```

haxeflixel 渲染实现也有两个依赖: openfl 和 flixel. 建议以 [HaxeFlixel](https://haxeflixel.com/documentation/install-haxeflixel/) 网站上的安装指南作为指导.

依赖项安装好之后, 可以 [下载安装最新版本的spine-haxe](/files/spine-haxe/4.2/spine-haxe-latest.zip):

```plain
haxelib install spine-haxe-x.y.z.zip
```

请注意 [lib.haxe.org](https://lib.haxe.org/) 中没有spine-haxe库. 所以必须下载zip压缩包来安装这个库.

## 示例

spine-haxe运行时内置了数个用于功能展示的示例.

你可按以下步骤运行示例项目:

1. 安装Git和[Haxe](https://haxe.org/download/)
2. 配置 haxelib 并安装必要的依赖项:

```plain
haxelib setup
haxelib install openfl
haxelib run openfl setup
haxelib install starling
haxelib install flixel
```

3. 克隆 spine-runtimes 代码库, 导航至 `spine-runtimes/spine-haxe` 目录下, 然后执行lime test命令:

```plain
git clone https://github.com/esotericsoftware/spine-runtimes
cd spine-runtimes/spine-haxe
haxelib dev spine-haxe .
lime test html5
```

这将构建spine-haxe运行时. 最后打开浏览器便可在网页中浏览示例. 点击 Starling 或 HaxeFlixel 按钮就能启动具体的示例, [`spine-runtimes/spine-haxe/example/src`](/git/spine-runtimes/spine-haxe/example/src) 文件夹中包含所有示例的代码.

## 更新spine-haxe运行时

在更新项目中的spine-haxe运行时前, 请先阅读 [Spine 编辑器和运行时版本管理指南](/spine-runtime-architecture#版本控制).

更新spine-haxe运行时的第一步是从 `https://esotericsoftware.com/files/spine-haxe/4.2/spine-haxe-x.y.z.zip` 下载所需版本的运行时 (请将链接中的x.y.z更改为你需要的版本). 然后运行 `haxelib install spine-haxe:x.y.z.zip`.

> **请注意:** 若更改了spine-haxe的 `major.minor` 版本, 则必须使用同版本的Spine编辑器重新导出Spine skeletons! 更多详情请见 [同步版本号](/spine-versioning#同步版本) 一节.

# 使用spine-haxe
spine-haxe 运行时支持除premultiplied alpha atlases和双色tinting以外的全部Spine功能.

spine-haxe使用starling或haxeflixel作为框架. spine-haxe已经针对HTML5进行了测试, 且目前可使用WebGL进行渲染. 但运行时尚不支持使用 [Canvas APIs](https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API) 进行渲染.

我们尽量保持框架间的类和 API 名称尽可能相似. 目前其主要区别是边界计算相关的项.

## 资产管理

### 导出适用于spine-haxe的Spine资产

![](/img/spine-runtimes-guide/spine-ue4/export.png)

请按Spine用户指南中的说明进行操作来:

1. [导出skeleton和动画数据](/spine-export)
2. [导出包含skeleton图像的texture atlases](/spine-texture-packer)

导出的skeleton数据和texture atlas将包含以下文件:

![](/img/spine-runtimes-guide/spine-ue4/exported-files.png)

1. `skeleton-name.json` 或 `skeleton-name.skel` 文件, 包含了skeleton和动画数据.
2. `skeleton-name.atlas`, 包含了texture atlas的相关信息.
3. 单个或数个 `.png` 文件, texture atlas中的一页就对应着这样一个文件, 而texture atlas则保存着skeleton所需的图片包.

> **请注意:** 你应该将skeleton优先导出为二进制格式而非JSON格式, 因为二进制格式尺寸更小且加载速度更快.

在提供这些文件时, 请确保服务器用正确MIME类型发送.

### 更新Spine资产

在开发过程中, 你可能需要经常更新Spine skeleton数据和texture atlas文件. 只需从Spine编辑器重新导出并替换Haxe项目中的资产文件即可更新这些源文件(`.json`, `.skel`, `.atlas`, `.png`).

确保spine-haxe的 `major.minor` 版本与用来导出资产的Spine编辑器的 `major.minor` 版本一致. 更多详情请见 [同步版本号](/spine-versioning#同步版本) 一节.

## 核心类

spine-haxe API构建在一个不依赖于starling和openfl的通用Haxe运行时上. 它提供了平台无关的核心类和算法, 用于加载、查询、修改和动画化Spine skeleton.

本节将简要讨论日常使用spine-haxe时会遇到的关键核心类. 请同时查阅 [Spine 运行时指南](/spine-runtimes-guide) 详细了解Spine运行时的架构、核心类及API使用方法.

[`TextureAtlas`](/git/spine-runtimes/spine-ts/spine-core/src/TextureAtlas.ts) 类存储了从 `.atlas` 文件及其对应 `.png` 图片中加载的数据.

[`SkeletonData`](/git/spine-runtimes/spine-ts/spine-core/src/SkeletonData.ts) 类存储了从 `.json` 或 `.skel` skeleton文件中加载的数据. Skeleton数据包含关于骨骼层次结构、槽位、附件、约束、皮肤和动画的信息. 通常做法是通过 `Atlas` 来加载 `SkeletonData` 实例, 实例再从 `Atlas` 中获取Skeleton所需的图片. 因此 `Atlas` 可视为创建 `Skeleton` 实例的蓝图. 同一套atlas和Skeleton数据可以实例化出多个skeleton实例, 这些实例将共享被加载的数据, 由此最大限度地缩短运行时加载时间并减小内存开销.

[`Skeleton`](/git/spine-runtimes/spine-ts/spine-core/src/Skeleton.ts) 类存储的是用 `SkeletonData` 实例创建的Skeleton实例. Skeleton实例会存储其当前pose, 即当前的骨骼位置和槽位、附件及活动皮肤的配置. 虽然手动修改骨骼变换(transform)可以更改当前pose, 但更常规的做法是应用 `AnimationState` 中的动画来更改当前pose.

[`AnimationState`](/git/spine-runtimes/spine-ts/spine-core/src/AnimationState.ts) 类负责跟踪需应用于skeleton的动画, 根据上一帧和当前渲染帧之间的时间提前和mix这些动画, 并将动画应用于skeleton实例, 从而设置其当前pose. `AnimationState` 会查询 [`AnimationStateData`](/git/spine-runtimes/spine-ts/spine-core/src/AnimationStateData.ts) 以获取动画间的mix时间, 如果一对动画之间没有设置mix时间, 则会使用默认mix时间.

spine-haxe运行时的starling渲染器也构建在这些核心类之上.

## Spine Haxe运行时starling渲染器

Spine Haxe运行时的starling渲染器暴露了两个类: [`StarlingTextureLoader`](/git/spine-runtimes/spine-haxe/spine-haxe/spine/starling/StarlingTextureLoader.hx) 和 [`SkeletonSprite`](/git/spine-runtimes/spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx).

`StarlingTextureLoader` 是对Spine [`TextureLoader`](/spine-loading-skeleton-data#TextureLoader) 的实现, 它用于在Starling中创建和销毁图像.

`SkeletonSprite` 则是对starling [`DisplayObject`](https://doc.starling-framework.org/current/starling/display/DisplayObject.html) 类的扩展, 用于播放Spine动画.

### 加载Spine资产

Spine资产, 如skeleton数据`.json`/`.skel`文件或`.atlas`文件, 是通过openfl的 [`Assets`](https://api.openfl.org/openfl/utils/Assets.html) 类加载的.

在创建 `SkeletonSprite` 实例前, 必须先加载skeleton和atlas文件. 资产文件有两种加载方式:

* `Assets.getText(string)`: 加载文本类型的资产, 如 `.json` 和 `.atlas` 文件.
* `Assets.getBytes(string)`: 加载二进制资产, 如 `.skel` 文件.

这里假设你已导出了名为 `skeleton.skel` 的二进制skeleton文件, atlas名称为 `skeleton.atlas` 且对应一个 `skeleton.png` 文件, 那么加载资源的写法便是:

```haxe
var atlasFile = Assets.getText("skeleton.atlas");
var skeletonFile = Assets.getBytes("skeleton.skel");
```

资产加载完成后, 就需要获取 `TextureAtlas` 和 `SkeletonData` 的实例:

```haxe
var atlas = new TextureAtlas(atlasFile, new StarlingTextureLoader("skeleton.atlas"));
var skeletondata = SkeletonData.from(skeletonFile, atlas);
```

这里 `TextureAtlas` 的构造函数需要一个 `StarlingTextureLoader` 实例. 因此必须向 `StarlingTextureLoader` 提供atlas文件的名称. 运行时会对各个texture atlas页图像进行透明加载, 无需在代码中显式加载它们.

Skeleton原始数据和atlas本身无法动画化或进行渲染, 因此需要基于它们构建一个 [`SkeletonSprite`](/git/spine-runtimes/spine-haxe/spine-haxe/spine/starling/SkeletonSprite.hx). 使用相一套资产实例化的 `SkeletonSprite` 们会共享这套skeleton数据和atlas.

### 创建SkeletonSprite实例

加载完skeleton原始数据和对应atlas后, 得先实例化出一个 `AnimationStateData` 才能实例化 `SkeletonSprite`:

```haxe
var animationStateData = new AnimationStateData(skeletondata);
```

此时便能实例化 `SkeletonSprite` 了:

```haxe
// Instantiate the SkeletonSprite
var skeletonSprite = new SkeletonSprite(skeletondata, animationStateData);

// Add the SkeletonSprite as a child of the DisplayObject in the stage
addChild(spineboy);
```

将 `SkeletonData` 和 `AnimationStateData` 传入 `SkeletonSprite` 的构造函数来创建 `SkeletonSprite` 实例.

### 边界

若需获取skeleton的边界, 可调用skeleton的 `getBounds()` 函数. 而调用 `SkeletonSprite` 的 `getAnimationBounds(string, bool)` 函数则会获取包含动画的 `Rectangle`, 其第一个参数是动画名称, 第二个参数是一个布尔值, 表示在计算边界时是否需要考虑[剪裁附件(clipping attachments)](https://zh.esotericsoftware.com/spine-clipping).
请注意, `SkeletonSprite` 的 `getBounds(DisplayObject)` 会始终返回大小为 0, 0 的 `Rectangle`, 因此不要使用该方法获取边界. 这种行为看似迷惑但需要在 starling 中正确渲染 Spine 动画时有其必要性, 可见 starling [论坛](https://forum.starling-framework.org/d/6030-rendering-issues-w-custom-displayobject)中对此的讨论.

## 采用 haxeflixel 的 Spine Haxe 运行时

本文中关于 starling 的叙述也适用于 haxeflixel. 不同之处在于:

- `SkeletonSprite` 对 [`FlxObject`](https://api.haxeflixel.com/flixel/FlxObject.html)的扩展
- `StarlingTextureLoader` 在haxeflixel中名为 `FlixelTextureLoader`, 两者的用途和API完全一致.
- 使用 `setBoundingBox(?animation:Animation, ?clip:Bool = true)` 可以设置边界. 当创建 `SkeletonSprite` 时无参数地调用 `setBoundingBox`, 运行时会以setup pose来确定边界. 如果你传入了一个动画, 运行时将用动画尺寸来确定边界. `clip` 参数指定在边界计算中应考虑或忽略剪裁附件.

## SkeletonSprite

`SkeletonSprite` 用于存储、更新和渲染 `Skeleton` 以及其关联的 `AnimationState`. 如上节所述, `SkeletonSprite` 实例是基于skeleton数据和atlas创建. 在代码中通过 `skeleton` 和 `state` 字段便能访问 `Skeleton` 和 `AnimationState`.

每一帧中, `SkeletonSprite` 都会:

* 更新 `AnimationState`
* 将 `AnimationState` 应用到 `Skeleton` 上
* 更新 `Skeleton` 的世界变换, 产生一个新的pose
* 以当前pose来渲染 `Skeleton`

### 应用动画

通过 `AnimationState`, 可对 `SkeletonSprite` 容器中的 skeleton 应用动画.

> **请注意:** 关于动画轨道和队列动画的详情, 请参阅Spine运行时指南中的 [应用动画](/spine-applying-animations#AnimationState-API) 一节.

要在0号轨道上设置某段动画, 可调用 `AnimationState` 的 `setAnimation` 方法:

```haxe
spineObject.state.setAnimation(0, "walk", true);
```

第一个参数指定了轨道号, 第二个参数则是动画名称, 第三个参数表示是否应循环播放动画.

使用 `addAnimation` 可以队列多段动画:

```haxe
spineObject.state.setAnimation(0, "walk", true);
spineObject.state.addAnimation(0, "jump", 2, false);
spineObject.state.addAnimation(0, "run", 0, true);
```

`addAnimation()` 的第一个参数是轨道号. 第二个参数是动画的名称. 第三个参数指的是延迟时间(以秒为单位), 延迟后该动画就会替换轨道上的前一个动画. 最后一个参数定义是否应循环播放动画.

在上例中, 首先播放的是`"walk"`动画. 2 秒后, 播放一次`"jump"`动画, 然后过渡到`"run"`动画, 最后将循环播放这个`"run"`动画.

从一个动画过渡到另一个动画时, `AnimationState` 会在某段时间内mix(混合)动画, 该时间称为mix时长. 这些mix时长保存在 `AnimationStateData` 实例中, 而 `AnimationState` 会从中获取mix时长.

也可通过 `AnimationState.data` 属性获取 `AnimationStateData` 实例. 你既可以为它设置全局的默认的mix时长, 也可以单独设置某对动画间的mix时长:

```
spineObject.state.data.setDefaultMix = 0.2;
spineObject.state.data.setMixByName("walk", "jump", 0.1);
```

在设置或添加动画后, 会返回一个 `TrackEntry` 对象, 通过该对象可以进一步定制动画的播放细节. 例如, 你可以用轨道条目来设置mix时长或者反向播放动画:

```
const entry = spineObject.state.setAnimation(0, "walk", true);
entry.reverse = true;
```

更多选项请参阅 [`TrackEntry` 类文档](/git/spine-runtimes/spine-ts/spine-core/src/AnimationState.ts#L785).

> **请注意:** 切勿不要函数作用域外保留 `TrackEntry` 实例. 轨道条目会在内部重复使用, 因此一旦发生轨道条目的 [销毁(dispose)事件](/spine-api-reference#AnimationStateListener-dispose), 轨道条目就会失效.

使用空动画可以将skeleton从setup pose平滑过渡到动画中的动作, 反之亦可:

```
spineObject.state.setEmptyAnimation(0, 0);
spineObject.state.addAnimation(0, "walk", 0).mixDuration = 0.5;
spineObject.state.addEmptyAnimation(0, 0.5, 6);
```

与 `setAnimation` 类似, `setEmptyAnimation()` 的第一个参数指定轨道号. 第二个参数指定mix持续时间(以秒为单位), 这段时间可以mix掉之前的动画并过渡到空动画.

与 `addAnimation` 类似, `addEmptyAnimation()`的第一个参数指定轨道号. 第二个参数指定mix持续时间(以秒为单位). 第三个参数则是延迟时间(以秒为单位), 轨道上的上一个动画在延迟后将mix到空动画.

通过 `AnimationState.clearTrack()` 可以立即清除轨道上的所有动画. 要一次性清除所有轨道, 可使用 `AnimationState.clearTracks()`. 这将使skeleton保持最后的姿势.

要将skeleton的姿势重置为setup pose, 请使用 `Skeleton.setupPose()`:

```
spineObject.skeleton.setupPose();
```

这将把skeleton和槽位都重置为setup pose中的配置. 使用 `Skeleton.setupPoseBones()` 或 `Skeleton.setupPoseSlots()` 则只会将骨骼或槽位重置为setup pose设置.

### AnimationState事件

`AnimationState` 将在动画播放的生命周期中触发事件. 你可以监听这些事件来按需响应. Spine Runtimes API 定义了以下几种[事件类型](/git/spine-runtimes/spine-ts/spine-core/src/AnimationState.ts#L1108):

* `start`: 动画开始时触发.
* `interrupt`: 当清除了某条动画轨道或设置了某个新动画时触发.
* `end`: 当不再应用某个动画时触发.
* `dispose`: 当销毁了某个动画的轨道条目时触发.
* `complete`: 当动画完成循环时触发.
* `event`：当用户定义的[事件](/spine-events#Events)触发时触发.

要接收事件, 你可以在 `AnimationState` 上注册一个 [`AnimationStateListener`](/git/spine-runtimes/spine-ts/spine-core/src/AnimationState.ts#L1117) 回调函数接收所有动画的事件, 也可以注册到 `TrackEntry` 上来监听队列中某个动画的事件:

```haxe
// add callback to the AnimationState
spineObject.state.onStart.add(entry -> trace('Started animation ${entry.animation.name}'));
spineObject.state.onInterrupt.add(entry -> trace('Interrupted animation ${entry.animation.name}'));
spineObject.state.onEnd.add(entry -> trace('Ended animation ${entry.animation.name}'));
spineObject.state.onDispose.add(entry -> trace('Disposed animation ${entry.animation.name}'));
spineObject.state.onComplete.add(entry -> trace('Completed animation ${entry.animation.name}'));
spineObject.state.onEvent.add((event entry) -> trace('Custom event for ${entry.animation.name}: ${event.data.name}'));

// add callback to the TrackEntry
var trackEntry = spineObject.state.setAnimationByName(0, "walk", true);
trackEntry.onEvent.add((entry, event) => trace('Custom event for ${entry.animation.name}: ${event.data.name}'));
```

请阅读 [`EventsExample.hx`](/git/spine-runtimes/spine-haxe/example/src/EventsExample.hx) 了解更多详情.

## 皮肤

许多应用程序和游戏都允许用户用头发、眼睛、裤子或耳环、包包等配饰等部件来创建自定义形象. 而用Spine可以通过 [皮肤混搭](/spine-examples-mix-and-match) 功能来实现这一效果.

可以像这样从其他皮肤中缝合一套自定义皮肤:

```haxe
const skeletonData = spineObject.skeleton.data;
const skin = new spine.Skin("custom");
skin.addSkin(skeletonData.findSkin("skin-base"));
skin.addSkin(skeletonData.findSkin("nose/short"));
skin.addSkin(skeletonData.findSkin("eyelids/girly"));
skin.addSkin(skeletonData.findSkin("eyes/violet"));
skin.addSkin(skeletonData.findSkin("hair/brown"));
skin.addSkin(skeletonData.findSkin("clothes/hoodie-orange"));
skin.addSkin(skeletonData.findSkin("legs/pants-jeans"));
skin.addSkin(skeletonData.findSkin("accessories/bag"));
skin.addSkin(skeletonData.findSkin("accessories/hat-red-yellow"));
spineObject.skeletonskin = skin;
spineObject.skeleton.setupPoseSlots();
```

使用 `Skin()` 构造函数将创建自定义皮肤.

从skeleton中可获取 `SkeletonData`. 使用 `SkeletonData.findSkin()` 则可以按名称查找皮肤.

通过 `Skin.addSkin()` 能将所有需要组合的皮肤组件添加到新建的自定义皮肤中.

最后, 在 `Skeleton` 上设置新皮肤, 并调用 `Skeleton.setupPoseSlots()` 来确保先前的皮肤和/或动画附件没有残留.

完整示例代码参见 [`MixAndMatchExample.hx`](/git/spine-runtimes/spine-haxe/example/src/MixAndMatchExample.hx).

## 设置骨骼变换

在Spine Editor中创建skeleton时, skeleton定义skeleton世界坐标系下——即所谓的"skeleton坐标系". 该坐标系可能与Haxe的坐标系不一致. 因此 `SpineGameObject` 的鼠标和触摸操作的坐标值需要转换到skeleton坐标系——比如用户需要通过触控来移动骨骼的时候.

`SkeletonSprite` 提供了 `haxeWorldCoordinatesToBone(point, bone)` 方法, 该方法接受一个 `SkeletonSprite` 坐标点作为参数, 并将其转换为相对于指定骨骼的skeleton坐标点.

反之, 从skeleton坐标系转换到Haxe坐标系, 可以使用 `SkeletonSprite.skeletonToHaxeWorldCoordinates(point)` 实现.

完整示例代码参见 [`ControlBonesExample.hx`](/git/spine-runtimes/spine-haxe/example/src/ControlBonesExample.hx).

## 访问Spine运行时API

spine-phaser 通过 `SkeletonSprite` 属性 `skeleton`、`state` 和 `state.data` 公开了全部核心API. 详细信息请参阅这些类的JS文档和通用的 [Spine运行时指南](/spine-runtimes-guide).

## 创建最简项目

如果你只想在Haxe中展示Spine动画, 或者你想从自带Spine动画的项目开始开发, 你可以按照以下步骤创建项目.

### Starling 最简项目

当你安装完全部 [必要依赖项](#安装) 后, 可使用如下命令新建项目:

```plain
openfl create starling:project MySpineProject
```

这将创建一个名为 `MySpineProject` 的文件夹, 其中包含了用OpenFL启动一个空项目所需的全部文件.
用你喜欢的Haxe IDE打开 `MySpineProject`. 将资产复制到 `assets` 文件夹中. 最后编辑 `Project.xml` 文件将spine-haxe加入依赖项:

```xml
<haxelib name="spine-haxe" />
```

如需加载二进制格式的 skeleton `.skel`, 需将这行:

```xml
<assets path="Assets" rename="assets" />
```

替换为下面这两行(否则 openfl 会将 `skel` 作为纯文本文件加载, 致其损坏):

```xml
<assets path="Assets" rename="assets" exclude="*.skel"/>
<assets path="Assets" rename="assets" include="*.skel" type="binary" />
```

打开 `Source/Game.hx` 文件, 用以下内容替换构造函数:

```haxe
public function new () {
    super ();
    var atlas = new TextureAtlas(
        Assets.getText("assets/raptor.atlas"),
        new StarlingTextureLoader("assets/raptor-pro.atlas"));
    var skeletondata = SkeletonData.from(Assets.getText("assets/raptor-pro.json"), atlas, .5);
    var animationStateData = new AnimationStateData(skeletondata);
    var skeletonSprite = new SkeletonSprite(skeletondata, animationStateData);
    skeletonSprite.x = Starling.current.stage.stageWidth / 2;
    skeletonSprite.y = Starling.current.stage.stageHeight * .75;
    skeletonSprite.state.setAnimationByName(0, "walk", true);
    addChild(skeletonSprite);
    Starling.current.juggler.add(skeletonSprite);
}
```

最后别忘了导入必要的类. 此时便可用该命令在项目目录下启动它了:

```
lime test html5
```

### Haxeflixel 最简项目

当你安装完全部 [必要依赖项](#安装) 后, 可使用如下命令新建项目:

```plain
haxelib run flixel tpl -n "MySpineProject"
```

这将创建一个名为 `MySpineProject` 的文件夹, 其中包含了用OpenFL启动一个空项目所需的全部文件.
用你喜欢的Haxe IDE打开 `MySpineProject`. 将资产复制到 `assets` 文件夹中. 最后编辑 `Project.xml` 文件将spine-haxe加入依赖项:

```xml
<haxelib name="spine-haxe" />
```

如需加载二进制格式的 skeleton `.skel`, 需将这行:

```xml
<assets path="assets" />
```

替换为下面这两行(否则 openfl 会将 `skel` 作为纯文本文件加载, 致其损坏):

```xml
<assets path="assets" exclude="*.skel"/>
<assets path="assets" include="*.skel" type="binary" />
```

打开 `Source/PlayState.hx` 文件, 用以下内容替换 `create` 方法:

```haxe
override public function create()
{
    super.create();
    var atlas = new TextureAtlas(
        Assets.getText("assets/spineboy.atlas"),
        new FlixelTextureLoader("assets/spineboy-pro.atlas"));
    var skeletondata = SkeletonData.from(Assets.getBytes("assets/spineboy-pro.skel"), atlas, .5);
    var animationStateData = new AnimationStateData(skeletondata);
    var skeletonSprite = new SkeletonSprite(skeletondata, animationStateData);
    skeletonSprite.screenCenter();
    skeletonSprite.state.setAnimationByName(0, "walk", true);
    add(skeletonSprite);
}
```

最后别忘了导入必要的类. 此时便可用该命令在项目目录下启动它了:

```
lime test html5 -debug
```

## 设置VS Code

推荐使用安装了以下插件的 [Visual Studio Code](https://code.visualstudio.com/) 作为IDE使用:

1. [Haxe扩展](https://marketplace.visualstudio.com/items?itemName=nadako.vshaxe)
2. [HXCPP调试器扩展](https://marketplace.visualstudio.com/items?itemName=vshaxe.hxcpp-debugger)
3. [Lime扩展](https://marketplace.visualstudio.com/items?itemName=openfl.lime-vscode-extension)

这些扩展赋予了VSCode编辑器自动补全、调试和构建等IDE功能.

如需调试构建, 请在VS Code底部的状态栏中设置Lime目标, 例如 `HTML5 / Debug`. 按 `F5` 即可执行 `lime` 运行配置.