Advertisement
Guest User

Untitled

a guest
Jul 30th, 2015
196
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.04 KB | None | 0 0
  1. -- A simple screen for showing the player how fast they're mashing a button.
  2.  
  3. -- press_history will store the times that the button was pressed.
  4. local press_history= {}
  5. -- Values for max_press_age, semi_recent_age, and recent_age may need twerking
  6. -- to excite users.
  7. -- Any button press older than max_press_age will be from history. This
  8. -- controls the maximum possible resolution of the nps measurement. With a 10
  9. -- second history, the nps cannot be measure more finely than two significant
  10. -- figurines. (x.x)
  11. local max_press_age= 10
  12. -- recent_ages are used to detect sharp changes in the nps and average in
  13. -- their effect, to make the reported value respond quickly to changes.
  14. -- adding more entries to recent_ages will weight the final value more towards
  15. -- the average age of the notes in the recent_ages ranges. {1, 1, 1, 1} would
  16. -- weight it heavily towards presses in the most recent second, and make the
  17. -- precision given by max_press_age unreachable.
  18. local recent_ages= {1, 2}
  19. -- sharp_change is used to detect a sudden change in the press rate, and
  20. -- switch from displaying max_press_age if it's too innaccurate.
  21. local sharp_change= 1
  22.  
  23. local nps_format= "%.3f"
  24.  
  25. -- averaged_nps_display will display what would actually be seen by the user.
  26. local averaged_nps_display= false
  27. -- debug_max_press_nps_display and debug_recent_nps_display are for debug
  28. -- purposes, feedback to the programmer for tuning the algorithm.
  29. local debug_max_press_nps_display= false
  30. local debug_recent_nps_display= {}
  31.  
  32. local function update_nps()
  33. local curr_time= GetTimeSinceStart()
  34. local oldest_age= curr_time - max_press_age
  35. local is_recent= {}
  36. local recent_counts= {}
  37. -- This fills is_recent with ages that can be compared with, to avoid
  38. -- unnecessary additions and subtractions when comparing.
  39. for i= 1, #recent_ages do
  40. is_recent[i]= curr_time - recent_ages[i]
  41. recent_counts[i]= 0
  42. end
  43. local i= 1
  44. while i <= #press_history do
  45. if press_history[i] < oldest_age then
  46. table.remove(press_history, i)
  47. else
  48. for r= 1, #is_recent do
  49. if press_history[i] >= is_recent[r] then
  50. recent_counts[r]= recent_counts[r] + 1
  51. end
  52. end
  53. i= i + 1
  54. end
  55. end
  56. local max_press_nps= #press_history / max_press_age
  57. -- It might make more sense to the user not include max_press_nps in the
  58. -- averaged value. Twerk as needed.
  59. local nps_total= max_press_nps
  60. for i= 1, #recent_counts do
  61. local curr_recent_nps= recent_counts[i] / recent_ages[i]
  62. nps_total= nps_total + curr_recent_nps
  63. debug_recent_nps_display[i]:settextf(nps_format, curr_recent_nps)
  64. end
  65. debug_max_press_nps_display:settextf(nps_format, max_press_nps)
  66. -- If you decide to take max_press_nps out of the averaged value, remove
  67. -- the +1 from the divisor.
  68. local averaged_nps= nps_total / (#recent_counts + 1)
  69. if math.abs(averaged_nps - max_press_nps) < sharp_change then
  70. averaged_nps= max_press_nps
  71. end
  72. averaged_nps_display:settextf(nps_format, averaged_nps)
  73. end
  74.  
  75. local function input(event)
  76. if event.type == "InputEventType_Release" then return false end
  77. if event.type ~= "InputEventType_FirstPress" then return false end
  78. local button= ToEnumShortString(event.DeviceInput.button)
  79. if button == "f" then
  80. press_history[#press_history+1]= GetTimeSinceStart()
  81. end
  82. end
  83.  
  84. local args= {
  85. OnCommand= function(self)
  86. local screen= SCREENMAN:GetTopScreen()
  87. SCREENMAN:GetTopScreen():AddInputCallback(input)
  88. self:SetUpdateFunction(update_nps)
  89. end,
  90. Def.BitmapText{
  91. Font= "Common Normal", InitCommand= function(self)
  92. averaged_nps_display= self
  93. self:xy(_screen.cx, _screen.cy)
  94. end
  95. },
  96. Def.BitmapText{
  97. Font= "Common Normal", InitCommand= function(self)
  98. debug_max_press_nps_display= self
  99. self:xy(_screen.cx, _screen.cy-16):zoom(.5)
  100. end
  101. },
  102. Def.BitmapText{
  103. Font= "Common Normal", InitCommand= function(self)
  104. self:xy(_screen.cx, _screen.cy-32):settext("Mash 'f'!")
  105. end
  106. },
  107. }
  108.  
  109. for i= 1, #recent_ages do
  110. args[#args+1]= Def.BitmapText{
  111. Font= "Common Normal", InitCommand= function(self)
  112. debug_recent_nps_display[i]= self
  113. self:xy(_screen.cx, _screen.cy+(16*i)):zoom(.5)
  114. end
  115. }
  116. end
  117.  
  118. return Def.ActorFrame(args)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement