我们游戏中两次切场景时间不能太短,所以我们在第一次切场景时记录当前时间,当用户再次切场景时使用判断记录的时间是否超过3秒,如果没有则提示“场景切换太频繁请等待xx秒再操作”,为了精确度量时间所以我用了lua的os.clock
API,代码如下
出现问题
local time = os.clock() local function checkTime() local now = os.clock() local remain = 3 + time - now if remain每次切场景前调用
changeScene()
就可以了,经过测试没出现问题,就上线了。 第二天就有玩家反馈说提示需要28496秒才能切场景,而这个时间并不是固定,有时多,有时少。解决历程
我设置的最大时间是3秒,显示结果竟然会大于3秒,肯定是
now
小于time
。但是为什么当前时间会小于过去的时间呢。我首先想到会不会是用户把时间调到之前的时间了,经测试还真的能够出现。 再跟玩家沟通后发现玩家并没有调整时间,再继续找问题。经过Google搜索一番,发现lua的os.clock()会调用c的clock函数,该函数返回值依赖于操作系统,但依然返回一个从启动到现在的cpu执行时间。 查看os.clock的源码也验证了这一点。
clock
函数有3个关键信息需要关心:
clock
返回cpu滴答次数而非秒数clock_t clock (void)
返回类型为clock_t
,该类型在32位系统中是4字节,64位系统中是8字节CLOCKS_PER_SEC
表示每秒钟的时钟滴答次数在mac上测试得到到
CLOCKS_PER_SEC
为1000000,也就是说clock()/CLOCKS_PER_SEC
为执行的秒数,如果在32位系统中有效时间最大为1小时10分钟。Android系统都是32位,而且玩家挂机时很容易就能超过1小时的运行时间,所以问题就出在了clock溢出了。 所以只需要将上面的代码从
os.clock
修改为os.time
就能解决当前时间小于过去时间的问题了。再谈os.clock
上面使用
os.time
替换了os.clock
解决了时间倒退的问题,但是丢失了时间的精度,因为os.time
最小精度为1秒。还好切场景等待时间误差1秒也没关系。有没有什么地方需要时间精度少于1秒呢,当然是有的,比如掉血后的血条过渡效果。
当显示血量从100掉到50时,血条需要花费1秒时间从100过渡到50,而不是立刻到达50。这时再用
os.time
将不能达到流畅的过渡效果,所以还得使用os.clock
。既然
os.clock
在32位系统有溢出问题,导致当前时间小于过去的时间,显然不能不做处理就直接使用。 由于需要度量的时间很小,不会超过1小时(os.clock在32位系统的最大时间),那么可以在检查到溢出时修正当前时间就好。local function clock(old) if not old then return os.clock() end local now = os.clock() if now总结
os.clock
特点:
- 可以度量小于1秒的时间
- 在32位系统中有溢出风险,最大可度量的时间为 4294.967296,约1小时10分钟
- 多线程/多进程中不同平台的返回时间不同
虽然os.clock有一些限制,但是在游戏中的一些短时间应用还是没有问题的。
» 本文链接地址:https://www.litefeel.com/lua-os-clock/
» 订阅本站:www.litefeel.com/feed/
» Host on Linode VPS
This post was last modified on 2019 年 02 月 25 日 01:34