0

实现 pixi + DragonBones 播放动画

 2 years ago
source link: https://segmentfault.com/a/1190000040636071
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

实现 pixi + DragonBones 播放动画

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

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

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

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

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

dragonbones里的示例

思路大概清晰了,里面大部分的动图都是用了骨骼动画制作的,顺着 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 做出一套简单的骨骼动画

  • 网上下的素材,莫商用

  • 纹理 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!完成。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK