实现 pixi + DragonBones 播放动画

雷电将军最近上线了,流水的主C,铁打的神。七神必抽,一个10发娶回家,还附赠一个小保底美滋滋。

实现 pixi + DragonBones 播放动画_第1张图片

当然,这篇文章不是为了凡,还是回到我们的主题:pixi 和 dragonbones

每次新老婆/老公上线之前,ys都会搞一个先导页面,比如这次雷神的先导页 https://webstatic.mihoyo.com/...

刚开始还以为是直接视频播放的,看了一下资源加载,诶,没有视频。强大的好奇心,找到了一张图

实现 pixi + DragonBones 播放动画_第2张图片

在脑海里搜寻了一番,想起来了,之前在用 egret 写小游戏的时候,有一个龙骨动画制作工具,示例里也是类似这样的 Sprite 图

实现 pixi + DragonBones 播放动画_第3张图片

思路大概清晰了,里面大部分的动图都是用了骨骼动画制作的,顺着 source 里的代码,找到了几个关键词

  • Spine

    查了一下,是一个制作2D骨骼动画的软件( Spine: 2D skeletal animation for games

    Spine-runtimes 几乎支持所有主流游戏引擎和编程语言,可以通过相对应地 runtimes 实现跟在Spine 编辑器一模一样的动画效果

  • Three.js

    这个众所周知,3D 库

大致的思路清晰了,先用 Spine 做出动画效果,导出数据,再用 spine-runtimes 的 three.js 插件将其在页面上运行起来。

那骨骼动画的好处是什么?

  • 连续。不会像帧动画放慢播放后出现卡顿的情况
  • 节约存储空间。

制作骨骼动画的软件有很多,上面找到的是 Spine,这软件我搜了一下,好家伙,要钱。虽说支持正版软件毋庸置疑,但作为开发也只是实践实践,不是特别想花这钱。只能看看有没有别的免费软件。

猛然想起,上面那条龙,egret 的龙骨制作软件,可以直接拿来做骨骼动画啊。这期间我还找到了它的工具库:格式互转。这个官方工具可以实现各种格式的互转,我这里要的是可以从 db JSON 转换成 Spine JSON 的命令:

db2 -t spine

先用 dragonebones 做出一套简单的骨骼动画

  • 纹理

    实现 pixi + DragonBones 播放动画_第4张图片

  • 纹理 JSON

    {"name":"ciwei","imagePath":"ciwei_tex.png","SubTexture":[{"name":"背部","x":1,"height":378,"y":1,"width":327},{"name":"手腕","x":278,"height":75,"y":381,"width":98},{"name":"身体","x":330,"height":268,"y":1,"width":300},{"name":"右手","x":171,"height":97,"y":381,"width":105},{"name":"右腿","x":330,"height":72,"y":271,"width":58},{"name":"枪","x":1,"height":88,"y":381,"width":168}],"height":512,"width":1024}
  • 骨骼 JSON

    {"frameRate":8,"name":"ciwei","version":"5.5","compatibleVersion":"5.5","armature":[{"type":"Armature","frameRate":8,"name":"Armature","aabb":{"x":-220.04,"y":-217.93,"width":482.27,"height":422.86},"bone":[{"name":"root","transform":{"skX":29.5962,"skY":29.5962}},{"name":"bone_ikTarget","parent":"root","transform":{"x":42.3759,"y":158.7024,"skX":-29.5962,"skY":-29.5962}},{"length":86,"name":"身体","parent":"root","transform":{"x":20.6596,"y":24.2253,"skX":13.7781,"skY":13.7781,"scX":1.2315,"scY":1.2315}},{"length":89,"name":"右手","parent":"身体","transform":{"x":-18.5603,"y":-11.6222,"skX":-47.9086,"skY":-47.9086,"scX":1.0534,"scY":1.0534}},{"length":200,"name":"背部","parent":"身体","transform":{"x":-17.7904,"y":-6.7476,"skX":-111.9925,"skY":-111.9925,"scX":0.812,"scY":0.812}},{"length":74,"name":"右腿","parent":"身体","transform":{"x":59.5746,"y":14.7124,"skX":11.4582,"skY":11.4582,"scX":0.812,"scY":0.812}},{"length":104,"name":"手腕","parent":"身体","transform":{"x":1.3965,"y":-3.7357,"skX":72.9018,"skY":72.9018,"scX":0.812,"scY":0.812}},{"length":95,"name":"枪","parent":"手腕","transform":{"x":108.0692,"y":9.1858,"skX":21.4831,"skY":21.4831}}],"slot":[{"name":"背部","parent":"背部"},{"name":"手腕","parent":"手腕"},{"name":"身体","parent":"身体"},{"name":"右手","parent":"右手"},{"name":"右腿","parent":"右腿"},{"name":"枪","parent":"枪"}],"ik":[{"chain":1,"name":"bone_ik","bone":"右腿","target":"bone_ikTarget"}],"skin":[{"slot":[{"name":"枪","display":[{"name":"枪","transform":{"x":37.82,"y":-13.56,"skX":176.9,"skY":176.9}}]},{"name":"身体","display":[{"name":"身体","transform":{"x":26.87,"y":-88.06,"skX":-86.23,"skY":-86.23,"scX":0.9615,"scY":0.9615}}]},{"name":"手腕","display":[{"name":"手腕","transform":{"x":71.91,"y":-1.08,"skX":-165.68,"skY":-165.68}}]},{"name":"右腿","display":[{"name":"右腿","transform":{"x":34.88,"y":5.16,"skX":-91.38,"skY":-91.38}}]},{"name":"背部","display":[{"name":"背部","transform":{"x":66.71,"y":-18.64,"skX":-0.6,"skY":-0.6}}]},{"name":"右手","display":[{"name":"右手","transform":{"x":71.25,"y":0.37,"skX":-35.83,"skY":-35.83,"scX":0.9493,"scY":0.9493}}]}]}],"animation":[{"duration":21,"playTimes":0,"name":"jump","bone":[{"name":"root","translateFrame":[{"duration":21,"x":1}]},{"name":"身体","translateFrame":[{"duration":7,"tweenEasing":0,"x":-23.02,"y":-20.28},{"duration":7,"tweenEasing":0,"x":-34.46,"y":-33.33},{"duration":7,"tweenEasing":0,"x":9.03,"y":9.82},{"duration":0,"x":-23.02,"y":-20.28}]}]}],"defaultActions":[{"gotoAndPlay":"jump"}]}]}

其实 pixi 官方可以直接 dragonebones 的插件,但任性,就是要转成 Spine 格式去载入。
执行 db2 -t spine 之后,会生成 ciwei_spine.json、ciwei_spine.altas两个文件,将纹理 png 和这两个文件放在项目里。现在我们可以开始写代码了。

  1. 安装依赖

    # pixi v6.1.2
    yarn add pixi.js
    
    # pixi-spine v3.0.8
    yarn add pixi-spine
  2. 导入

    import { Application, utils } from 'pixi.js'
    import { Spine } from 'pixi-spine'
  3. 实例化 pixi

    const app = new Application({
      view: this.$refs['canvas'],
      backgroundColor: 0x000000,
      antialias: true,
      width: this.width, // 舞台宽度
      height: this.height, // 舞台高度
      resolution: 2
    })
  4. 加载资源

    const loader = app.loader
    const resources = [{
      name: 'ciwei',
      url: './static/spine2/ciwei.json'
    }]
    // 加载资源
    resources.forEach(res => {
      loader.add(res.name, res.url)
    })
    
    // 加载成功
    loader.load(this.init)
  5. 添加对象到舞台

    function init () {
      // 获取 spine 骨骼对象
      const spine = new Spine(loader.resources['ciwei'].spineData)
      spine.name = 'ciwei'
      // 定义了 jump 的动画行为
      spine.state.setAnimation(0, 'jump', true)
      spine.x = 200
      spine.y = 200
      // 添加到舞台
      app.stage.addChild(spine)
    }

最终效果:

不过,实际也不需要像我这么绕,从 db 导出来的龙骨,官方是支持 pixi 的,贴上地址 DragoneBonesJS

最后看下我跑出来的雷电将军

Done!完成。

你可能感兴趣的