Corona SDK精确计时器

大家好 在这篇简短的文章中,我将告诉您如何在Corona SDK上的应用程序中创建计时器,并具有可接受的读取精度指标。 我们还考虑了标准计时器的问题所在。

本文中将解决以下问题:制作一个应用程序,该应用程序显示自打开应用程序以来每秒经过1次更新所经过的时间。

1.显而易见的标准解决方案。


创建一个标准计时器并显示其刻度。

timeout = 1000 timer.performWithDelay( timeout,function(event) print(event.count) end,0) 

一切似乎都是显而易见的,但是此解决方案的功能包括:

  • 首先,标准计时器能够正确正确地计算出从300-400ms开始的超时,并且低于此值的所有内容都会开始显着滞后,但是我们的情况有所不同,因为超时超过了指定的限制。 计时器的最小滴答周期(如果您指定1 ms)为1 / fps,即 60帧为16.(6)毫秒,30帧为33.(3)毫秒。
  • 其次,即使在所示的相对准确的周期内,每个刻度也存在大约5-10毫秒的随机误差,即 一个小时内出现15-30秒的错误。 通过在创建计时器时从参数中指定的值减去5毫秒,可以部分解决此问题。 而不是1000,请指定995。
  • 第三,如果由于其他代码的结果或设备的不稳定操作而导致应用程序中出现小条带,这些条带也将添加到计时器的积压中。
  • 第四,如果将应用程序最小化了一段时间然后重新部署,则从应用程序运行的秒数中将排除应用程序最小化的所有时间。

2.好的决定。


为了解决前一种方法的问题,我们使用以下设计,在这种方法中,我们使用了可能的最高速度的计时器,但是滴答计时器的信号将基于系统确切时间的来源进行计算。

 local timeout = 1000-- socket = require "socket" local start_time = socket.gettime()*1000--  ( ) local good_time = 0 timer.performWithDelay( 1,function(event) local new_time = socket.gettime()*1000--   local total_time = new_time - start_time--      local num = math.floor(total_time/timeout)--      timeout if num > good_time then--     good_time = num--  print(good_time) end end,0) 

我们分析这种方法的特点。 尽管如上所述我们指示的滴答频率为1ms,但实际的滴答量子将每16(33)-50ms执行一次,这将确定上述方法的最大可能误差,该误差将在0..50ms范围内变化。滴答滴答,即 滴答声重复率将比第一种方法不稳定,但是在任何距离(甚至几年)内此误差的值都将相同,即 即使一年后,相对于第一个刻度,我们的下一个刻度也将在相同范围内出现错误。

3.结果验证


我将举一个例子说明如何验证以上所有方面的公正性。 给定的源将每秒显示一次(分别)从打开该应用程序以来的当前时间,并显示操作期间累积的错误。

 local timeout = 1000 socket = require "socket" local start_time = socket.gettime()*1000--   local good_time = 0--   local bad_time = 0--   --  timer.performWithDelay( timeout,function(event) bad_time = event.count local bad_delta = (socket.gettime()*1000 - start_time) - (bad_time*timeout) print('Bad tick: '..bad_time, 'Delta: '..bad_delta) end,0) --  timer.performWithDelay( 1,function(event) local new_time = socket.gettime()*1000 local total_time = new_time - start_time local num = math.floor(total_time/timeout) if num > good_time then good_time = num local good_delta = (socket.gettime()*1000 - start_time) - (good_time*timeout) print('Good tick: '..good_time, 'Delta: '..good_delta) end end,0) 

祝大家好运!

Source: https://habr.com/ru/post/zh-CN422443/


All Articles