添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

我们游戏中两次切场景时间不能太短,所以我们在第一次切场景时记录当前时间,当用户再次切场景时使用判断记录的时间是否超过3秒,如果没有则提示“场景切换太频繁请等待xx秒再操作”,为了精确度量时间所以我用了lua的 os.clock API,代码如下

local time = os.clock()
local function checkTime()
    local now = os.clock()
    local remain = 3 + time - now
    if remain <= 0 then
        time = now
        return true
    -- 显示提示
    return false
local function changeScene()
    if checkTime() then
        -- 真正的切场景

每次切场景前调用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()
        local now = os.clock()
        if now < old then
            -- 4294.967296 = math.pow(2, 32)/CLOCKS_PER_SEC
            now = now + 4294.967296
        return now
    -- 使用
    local begin = clock()
    local function delatTime()
        return clock() - begin
    

    os.clock特点:

  • 可以度量小于1秒的时间
  • 在32位系统中有溢出风险,最大可度量的时间为 4294.967296,约1小时10分钟
  • 多线程/多进程中不同平台的返回时间不同
  • 虽然os.clock有一些限制,但是在游戏中的一些短时间应用还是没有问题的。

    标签: ,
  • 重新打包APK
  • Unity CSharp 热更新
  • 启用IPV6
  • 判断矩形相交
  • 使用Fail2Ban阻止VPS被攻击
  • 给MUMU模拟器设置代理
  • Unity2017的新spriteAtlas
  • Unity3d中超大图的bug
  • 在Windows上轻松切换不同版本Python
  • 游戏中的多时区问题
  • Other
  • WordPress
  •