第三十九篇(书中 11.12 ~ 11.15 节 内容)
这篇日记写完,龙骨篇就结束了。
最难的点就是掌握龙骨动画类的封装。
开始 11.12 节。
重点:
1、创建帧项目,改名,拖入图片。
操作:
1、创建帧项目,改名,拖入图片。
创建帧项目。
改名,拖入PNG图片。
至此,11.12 节结束。
开始 11.13 节。
重点:
1、导出帧动画为二进制格式。
2、运行动画。
操作:
1、导出帧动画为二进制格式。
导出为二进制。
导入Egret。
2、运行动画。
编写代码,并运行。
至此,11.13 节 结束。
开始 11.14 节。
额。。。不懂,等以后再说吧。
至此,11.14 节 结束。
开始 11.15 节。
重点:
1、动画加载的场景 。
2、资源命名。
3、异步加载。
4、构建播放动画主体类 DBPlayer ,事件类通知类 Handler。
5、实例化运行代码。
操作:
1、动画加载的场景 。
如果资源太大,一次性加载没有用到的资源,会影响性能和用户体验。
所以资源太大的情况下,应该选择按需加载。
资源尽量控制在2MB以下,如果超过,则用进度条的方式提醒用户。
2、资源命名。
3、异步加载。
4、构建播放动画主体类 DBPlayer ,事件类通知类 Handler。
我直接上代码。注意,我使用的动画解析方式是 二进制格式 。
1 export class DBPlayer extends egret.Sprite { 2 constructor() { 3 super(); 4 } 5 6 /** 当动画执行完毕后执行的函数 */ 7 public completeFun: Handler; 8 9 private armature: dragonBones.EgretArmatureDisplay; 10 private dragonFactory: dragonBones.EgretFactory; 11 12 //设置要添加的舞台层 13 private mparent: egret.DisplayObjectContainer; 14 15 //资源ID 16 private resourceId: string = ""; 17 18 //动画名称 19 private animationName: string = ""; 20 21 //骨骼名称 22 private armatureName: string = ""; 23 24 //播放次数 25 private playtime: number = 0; 26 27 //加载次数 28 private loadNum: number = 0; 29 30 //加载列表 31 private loadList: Array<any>; 32 33 34 public static getDBPlayer(): DBPlayer { 35 return new DBPlayer(); 36 } 37 38 /** 展示 */ 39 public show(resourceId, parent: egret.DisplayObjectContainer = null, playtime: number = -1, animationName: string, armatureName: string) { 40 this.mparent = parent; 41 this.resourceId = resourceId; 42 this.animationName = animationName; 43 this.armatureName = armatureName; 44 this.playtime = playtime; 45 46 let dragonData = RES.getRes(resourceId + "_ske_dbbin"); 47 let textureData = RES.getRes(resourceId + "_tex_json"); 48 let texture = RES.getRes(resourceId + "_tex_png"); 49 50 //如果 加载不到 动画资源,则使用异步加载的方式。 51 if (dragonData && textureData && texture) { 52 this.initDBData(dragonData, textureData, texture); 53 } else { 54 this.loadList = [ 55 resourceId + "_ske_dbbin", 56 resourceId + "_tex_json", 57 resourceId + "_tex_png" 58 ]; 59 this.loadNum = this.loadList.length; 60 this.startload(); 61 62 } 63 } 64 /** 开始加载动画资源 */ 65 private startload() { 66 67 //如果 资源数组里还有资源,则继续异步加载 68 if (this.loadList.length > 0) { 69 70 let res = this.loadList.pop(); 71 RES.addEventListener( 72 RES.ResourceEvent.GROUP_LOAD_ERROR, 73 this.onResourceLoadError, 74 this 75 ); 76 RES.getResAsync(res, this.compFunc, this); 77 } 78 } 79 80 /** 资源加载失败的情况 */ 81 private onResourceLoadError(event: RES.ResourceEvent) { 82 83 } 84 85 //异步加载资源完成后,继续加载下一个资源。 86 private compFunc() { 87 88 RES.removeEventListener( 89 RES.ResourceEvent.GROUP_LOAD_ERROR, 90 this.onResourceLoadError, 91 this 92 ); 93 this.loadNum--; 94 if (this.loadNum > 0) { 95 this.startload(); 96 } 97 // 书中的这部分代码我感觉没必要 上面都写了 98 // else { 99 // let dragonData = RES.getRes(this.resourceId + "ske_json"); 100 // let textureData = RES.getRes(this.resourceId + "tex_json"); 101 // let texture = RES.getRes(this.resourceId + "tex_png"); 102 // this.initDBData(dragonData, textureData, texture); 103 // } 104 } 105 106 //开始 载入数据、纹理,并且播放动画 107 private initDBData(dragonData: any, textureData: any, texture: any) { 108 109 //载入 解析 动画资源 110 this.dragonFactory = dragonBones.EgretFactory.factory; 111 this.dragonFactory.parseDragonBonesData(dragonData); 112 this.dragonFactory.parseTextureAtlasData(textureData, texture); 113 this.armature = this.dragonFactory.buildArmatureDisplay(this.armatureName); 114 115 this.armature.addEventListener( 116 dragonBones.AnimationEvent.COMPLETE, 117 this.onLoopComplete, 118 this 119 ); 120 121 //把 动画添加到容器 并且开始播放动画 122 this.addChild(this.armature); 123 this.play(0, this.playtime); 124 if (this.mparent) { 125 this.mparent.addChild(this); 126 } 127 } 128 129 //如果动画播放完毕,则 this.completeFun 向外部发送通知 130 private onLoopComplete(event: dragonBones.AnimationEvent) { 131 if (this.completeFun != null) { 132 this.completeFun.fun.call(this.completeFun.thisObj, this); 133 } 134 } 135 136 /** 播放 */ 137 public play(time: number, playTime: number = 5) { 138 if (this.armature) { 139 this.armature.animation.play(this.animationName, playTime); 140 141 //书中的这个播放方法无效,所以我改成了上面的方式 142 // this.armature.animation.gotoAndPlayByTime( 143 // this.animationName, 144 // time, 145 // playTime 146 // ); 147 } 148 } 149 150 /** 停止 */ 151 public stop() { 152 if (this.armature) { 153 this.armature.animation.stop(); 154 } 155 } 156 157 /** 卸载动画 */ 158 public unload() { 159 this.stop(); 160 if (this.armature) { 161 this.removeChild(this.armature); 162 } 163 if (this.mparent) { 164 this.mparent.removeChild(this); 165 } 166 this.armature = null; 167 } 168 169 170 } 171 172 /** 事件类 */ 173 export class Handler { 174 175 constructor(fun: Function = null, thisObj: any = null) { 176 this.fun = fun; 177 this.thisObj = thisObj; 178 } 179 /** 处理函数 */ 180 public fun: Function; 181 /** 处理函数所属对象 */ 182 public thisObj: any; 183 184 public dispose() { 185 this.fun = null; 186 this.thisObj = null; 187 } 188 189 /** 创建 Handler */ 190 public static create(fun: Function = null, thisObj: any = null) { 191 return new Handler(fun, thisObj); 192 } 193 }
5、实例化运行代码。
至此,11.15 节 结束。