Lua游戏逻辑开发中的优化思路
来源:互联网 发布:广州淘宝服装加工厂 编辑:程序博客网 时间:2024/06/04 17:59
本篇中,我们主要讲到一些Lua游戏逻辑开发中的优化思路,以及我们项目中的一部分应用。
开始之前,我们先说个题外话。编者认为,对于个人而言,程序高效可能会高于维护性。但对于团队合作来说,往往易懂、易维护、易扩展,稳定是基本要求,再去追求极致。
这里的高效都是相对的,作为一名程序员来说,我觉得高效应该是一种习惯和追求。
扯了一下,回归正题,这节里我们先从7个点来介绍。
1. 接口统一、抽象化
避免代码过多的Ctrl+C、Ctrl+V,把通用部分抽象化或者统一管理,让代码易读性更强,维护起来也更加方便。
大家看下一下这段代码。
if vo.cd_time == 0 then self.cdTimeTxt:setVisible(false) UITools.loadTexturesFromPilst(self.upBtn, "ui/commonUI/btnBG10.png", "ui/commonUI/commonUI") self.tipsTxt:setVisible(false) if vo.goods_num >= vo.cost_coin then self:setButtonEffect(true) else self:setButtonEffect(false) end if vo.is_tupo == 1 then self.panel1:setVisible(false) self.panel2:setVisible(true) self.istopo = true self.upBtn:setTitleText(AwakeWords[3]) self.light = ActionTimeLineUtils.getAnimate(resPth3, "action", nil, true) local x1,y1 = self.Image_2:getPosition() self.light:setPosition(x1,y1) self.light:setScale(2) self.root:addChild(self.light) else removeLight() self.istopo = false self.panel1:setVisible(true) self.panel2:setVisible(false) self.upBtn:setTitleText(AwakeWords[4]) local roleLv = RoleController:getInstance().model.mainRoleVo.lv local roleVip = RoleController:getInstance().model.mainRoleVo.vip if vo.need_lv > roleLv then self.suoImg:setVisible(true) self.lvTxt:setVisible(true) self.autoTxt:setVisible(false) self.checkBox:setVisible(false) self.lvTxt:setString(string.format(AwakeWords[18],vo.need_lv)) elseif vo.need_vip > roleVip then self.suoImg:setVisible(true) self.lvTxt:setVisible(true) self.autoTxt:setVisible(false) self.checkBox:setVisible(false) self.lvTxt:setString(string.format(AwakeWords[22],vo.need_vip)) else self.autoTxt:setVisible(true) self.checkBox:setVisible(true) self.suoImg:setVisible(false) self.lvTxt:setVisible(false) end if vo.leave_times > 0 then self.qipao:setVisible(true) self.vip:setSpriteFrame(UITools.getSpriteFrameFromPlist(string.format("ui/commonUIip/V%s.png",vo.vip_lv))) self.banjiaNum:setString(string.format(AwakeWords[19],vo.leave_times,vo.max_times)) else self.qipao:setVisible(false) end end else self:setButtonEffect(false) UITools.loadTexturesFromPilst(self.upBtn, "ui/commonUI/btnGray1.png", "ui/commonUI/commonUI") self.tipsTxt:setVisible(true) self.panel1:setVisible(false) self.panel2:setVisible(false) self.cdTimeTxt:setVisible(true) self.upBtn:setTitleText("") self:showDownTime(vo.cd_time) end
看完这段代码,心里只有一个字:累!
代码质量不高,维护也容易遗漏,并且在同个UI中,多处存在这种代码,这种情形大家就要注意统一下接口。
2. 模块解耦
1)在常用的游戏框架里常用MVC来使业务逻辑、数据、界面显示分离。
2)在模块中,我们常用的设计模式就是观察者,通常都会使用事件机制来降低耦合性。
3)去除相关依赖,在数据缺失的情况下界面并不会报错卡住。
3. 异步加载、分帧加载
对于大贴图以及一些解析慢的文件,尽量不要在主线程加载,采用异步加载来保证游戏的流畅性。
而分帧加载我们经常用在一些节点个数非常多的界面里,例如背包界面,通常都会策略加载或者分帧加载来确保打开时跳帧;还有MMO中的场景元素,也经常会通过分帧处理,降低单帧内创建压力。
4. 空间、时间的平衡
空间复杂度,时间复杂度通常调优就是内存与CPU占用的平衡(这里不排出两种都可以调到极致)。
在for循环使用过程中,要注意嵌套多深,n有多大,可以适当牺牲一些空间,设计出效率更优的解决方案。有时Hash表的运用也可以大程度的降低遍历的时间复杂度。
5. 缓存的应用
创建、释放频繁的对象,我们在游戏中往往也会通过一些缓存机制来处理,提高加载速度,同时也降低内存申请释放的次数,减少一些内存碎片。
举个简单的例子,对于一些通用的游戏UI贴图,我们就可以采用缓存来保证每次用到时无需加载,当然也得把握好当前内存,内存峰值。
6. table的消耗
在我们游戏中经常会用到table.insert/ table.remove,一般都不会有什么问题,但是当表里元素非常多的时候,从中间插入和移除就会有一定的性能损耗,遇到类似情况可考虑一些优化方案(第7中也是一种替代方案)。
7. 双链表
下面分享一下我们项目中常用的双链表,相信很多人的项目也都有用到。
list = {}function list.new(num) if not num then return {first = 0, last = -1} else return {first = num, last = num - 1} endendfunction list.size(list) if list.first > list.last then return 0 else return list.last + 1 - list.first endendfunction list.empty(list) return list.first > list.lastendfunction list.get(list, index) local index = list.first + index return list[index] endfunction list.pushFront(list, value) local first = list.first - 1 list.first = first list[first] = valueendfunction list.pushBack(list, value) local last = list.last + 1 list.last = last list[last] = valueendfunction list.popFront(list) local first = list.first if first > list.last then error("list is empty") end local value = list[first] list[first] = nil -- to allow garbage collection list.first = first + 1 return valueendfunction list.popBack(list) local last = list.last if list.first > last then error("list is empty") end local value = list[last] list[last] = nil -- to allow garbage collection list.last = last - 1 return valueend
最后在分享两个Lua源码中的技巧。
1.使用readonly表,保证一些数据不会被串改
setmetatable(g,{__index=G,__newindex=f})
2.Lua中next关键字,通过next来清空table
--遍历表元素while true do local k = next(t) if not k then break end t[k] = nilend--判断(任意)表是否为空if next(t) == nil then -- 表为空 -- ...end
东西太多,未完待续- -~
- Lua游戏逻辑开发中的优化思路
- 游戏逻辑层在Lua中的内存泄漏与防范
- Lua游戏最大签到逻辑
- 游戏功能逻辑优化
- lua学习:游戏中的Lua
- 游戏中的逻辑
- 游戏开发学习思路
- 游戏开发中的人工智能(十):模糊逻辑
- 游戏逻辑层在Lua中的内存泄漏与防范【转】
- Android游戏开发中的优化策略
- Lua游戏开发 0
- Lua游戏开发 语法
- Lua游戏开发学习
- quick+lua开发游戏
- 漫谈游戏中的交易逻辑
- 游戏中的刷兵逻辑
- 网页游戏开发思路分享
- Lua游戏脚本开发1 -- 初始化Lua
- FlowDroid获取APK的函数调用图
- Webpack2 完整踩坑教程(三)
- 基于swoole扩展实现真正的PHP数据库连接池
- springmvc,freemarker模式下脚本注入问题
- 蓝桥杯【历届试题】九宫重排
- Lua游戏逻辑开发中的优化思路
- 串口发送一帧数据时,两个字节的间隔时间是多少?
- poj_3422_Kaka's Matrix Travels
- 文章标题
- tcp协议ack以及乱序报文暂存的实现--立即ack/延迟ack/捎带ack
- Android5.0之CardView的使用
- 单例模式引起的内存泄漏
- protobuf C#编译
- MFC多线程