雷电将军最近上线了,流水的主C,铁打的神。七神必抽,一个10发娶回家,还附赠一个小保底美滋滋。
当然,这篇文章不是为了凡,还是回到我们的主题:pixi 和 dragonbones
每次新老婆/老公上线之前,ys都会搞一个先导页面,比如这次雷神的先导页 https://webstatic.mihoyo.com/...。
刚开始还以为是直接视频播放的,看了一下资源加载,诶,没有视频。强大的好奇心,找到了一张图
在脑海里搜寻了一番,想起来了,之前在用 egret 写小游戏的时候,有一个龙骨动画制作工具,示例里也是类似这样的 Sprite 图
思路大概清晰了,里面大部分的动图都是用了骨骼动画制作的,顺着 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 和这两个文件放在项目里。现在我们可以开始写代码了。
安装依赖
# pixi v6.1.2 yarn add pixi.js # pixi-spine v3.0.8 yarn add pixi-spine
导入
import { Application, utils } from 'pixi.js' import { Spine } from 'pixi-spine'
实例化 pixi
const app = new Application({ view: this.$refs['canvas'], backgroundColor: 0x000000, antialias: true, width: this.width, // 舞台宽度 height: this.height, // 舞台高度 resolution: 2 })
加载资源
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)
添加对象到舞台
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!完成。