11RIA 闪客社区 - 最赞 Animate Flash 论坛

搜索
查看: 2764|回复: 9
上一主题 下一主题

[AS 开发 & 技巧] 对声音播放使用简单的 Worker(多线程) 降低游戏卡顿,以及一些 Worker 使用技巧

[复制链接] TA的其它主题
发表于 2020-2-20 17:59:06 | 显示全部楼层 |阅读模式

【游客模式】——注册会员,加入11RIA 闪客社区吧!一起见证Flash的再次辉煌……

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
本帖最后由 TKCB 于 2020-2-20 22:47 编辑

flash/AIR解决方案中,
对嵌入在swf/swc中的声音进行播放不会引起明显卡顿,
但是对调用loadSound或首次播放操作会造成游戏卡顿。
如此scout截图。
QQ截图20200220174056.png


黄色柱部分,标记为“网络和视频”的,是声音loadSound或者首次播放开销
推测为loadSound中打开文件流、mp3初步解压等造成。
此开销是同步的,即使在PC也会造成游戏卡顿,在手机客户端上更加明显。

解决的方案,利用worker将其变为异步。
此worker代码不多,不会改变已有项目结构,对已上线的项目也能安全使用。
个人认为有做的价值。

主项目初始化worker代码

  1. worker = WorkerDomain.current.createWorker(loader.data, true);
  2. outputStream = Worker.current.createMessageChannel(worker);
  3. inputStream = worker.createMessageChannel(Worker.current);
  4. worker.setSharedProperty("w2m", inputStream);
  5. worker.setSharedProperty("m2w", outputStream)

复制代码


worker项目构造函数

  1. outputStream = Worker.current.getSharedProperty("w2m")
  2. inputStream = Worker.current.getSharedProperty("m2w");
  3. inputStream.addEventListener(Event.CHANNEL_MESSAGE, onInput);

复制代码




主项目在需要加载和播放声音时,用调用worker取代之前的sound.loadSound和sound.play

  1. outputStream.send({soundAddress:声音文件地址, command:"loadSound"})
  2. outputStream.send({soundAddress:声音文件地址, command:"play"})
复制代码

worker的对接代码

  1. public var soundDic:Dictionary = new Dictionary
  2. public function onInput(event:Event):void
  3. {
  4.         while(inputStream.messageAvailable){
  5.                 var obj:Object = inputStream.receive();
  6.                 switch(obj.command){
  7.                         case "play":
  8.                                 soundDic[obj.soundAddress].play()
  9.                                 break
  10.                         case "loadSound":
  11.                                 if(!soundDic[obj.soundAddress]){
  12.                                         soundDic[obj.soundAddress] = new Sound
  13.                                 }
  14.                                 soundDic[soundDic[obj.soundAddress]].loadSound(new URLRequest(obj.soundAddress));
  15.                                 break
  16.                 }
  17.         }

  18. }
复制代码

一些扩展,例如设置音量、中途停止声音等,可以以此格式编写。



此后声音加载消耗会转移到cpu的其他核心上,
主项目的声音加载消耗变成0,避免声音加载时造成游戏的瞬间卡顿。


一些值得注意事项:
在IOS上实测worker可以使用,甚至能用来热更。
作为worker的swf如果不能正常加载,试导出发布版的swf
在scout上开启 “编辑>首选项>测试版功能>启用用于ActionScript Worker的会话” 即可在Scout上查看worker的trace
即使能通过scout看trace,仍强烈推荐对worker执行部分进行try...catch并把错误信息发送给主项目处理
在用户客户端,主项目检查到worker不可用时,不管什么原因可以无缝切换回原来的声音在主项目播放的模式。
从主项目传递声音地址到worker时,可接受"app:/"开头的地址,但是不能传递"app-storage:/"的地址。worker对app-storage的指向和原本项目不同。一定传递的话,可改为传递new File(原地址).nativePath

评分

参与人数 1银子 +30 金子 +1 贡献 +3 收起 理由
TKCB + 30 + 1 + 3 11RIA 对大神的敬仰,如滔滔江水连绵不绝~~.

查看全部评分

 楼主| 发表于 2020-2-20 18:06:20 | 显示全部楼层
除播放声音外,另有几项推荐迁移到worker的部分
均为几乎不会影响原本代码,同时能比较大幅提高游戏性能的部分。

手机项目上,使用ETC1压缩纹理,在某些机型GPU上会产生迷宫格,
为解决这个问题,只能使用ETC1不压缩纹理,文件体积巨大。\
(参考:最高质量纹理,压缩前4MB压缩后380KB,质量10纹理,压缩前4MB压缩后100KB)

打成APK包时会自动对这些纹理ZIP压缩一次,使其体积不是特别明显
但是在IPA包上不会,以及用于更新的素材发送到用户的app-storage目录的也不会压缩,
作为巨大的文件保存在用户手机上

可将提供给苹果或准备放在用户app-storage目录的纹理使用ZIP压缩后放在对应位置
应AIR运行时的ByteArray.uncompress是同步方法,并且开销大
将需要解压的文件地址丢给worker执行,worker执行完毕后通过sharable==true的ByteArray返给主项目,
再由主项目上传显卡,此过程可避免游戏卡顿的同时缩小包体体积。

以我公司实际例子,进行此优化后最糟糕的包体体积从5GB下降到1.7GB,几乎未增加卡顿,效果显著。
回复

使用道具 举报

发表于 2020-2-20 22:42:51 | 显示全部楼层
将军写的很好,由于我没有实际需要,未对worker做深入研究,而且我也不做游戏。

不过这些技巧,仍然是非常重要的,值得大家学习。
回复

使用道具 举报

发表于 2020-2-20 22:47:57 | 显示全部楼层
【11RIA 闪客社区,评分公示】:
是否有价值:优秀(银子 +30  贡献 +3)
是否原创:是(金子 +1)
是否翻译:否
如对自己的评分有疑问,则咨询版主、管理员等。
回复

使用道具 举报

发表于 2020-3-5 10:53:18 | 显示全部楼层
写得真好
回复

使用道具 举报

发表于 2020-3-6 00:17:22 | 显示全部楼层
超赞的文章!!
回复

使用道具 举报

发表于 2020-7-14 21:01:22 | 显示全部楼层
受益匪浅啊!大赞!!
回复

使用道具 举报

发表于 2020-9-18 12:32:56 | 显示全部楼层
采用副线程处理音频加载播放任务后发现游戏不能安装到中文目录下了
@general_clarke
回复

使用道具 举报

发表于 2020-9-25 09:12:18 | 显示全部楼层
将军是开发垣克那位大神么,全局侦听控制类也是你的作品
回复

使用道具 举报

发表于 2020-10-5 15:03:38 | 显示全部楼层
不错不错!赞
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

感谢所有支持论坛的朋友:下面展示最新的5位赞助和充值的朋友……更多赞助和充值朋友的信息,请查看:永远的感谢名单

SGlW(66139)、 anghuo(841)、 whdsyes(255)、 longxia(60904)、 囫囵吞澡(58054)

下面展示总排行榜的前3名(T1-T3)和今年排行榜的前3名的朋友(C1-C3)……更多信息,请查看:总排行榜今年排行榜

T1. fhqu1462(969)、 T2. lwlpluto(14232)、 T3. 1367926921(962)  |  C1. anghuo(147)、 C2. fdisker(27945)、 C3. 囫囵吞澡(58054)



快速回复 返回顶部 返回列表