I needed a stopwatch / timer with pause and restart functionality for my game. So I created a simple test main.lua file and I thought some of you might find it useful. It’s using the concept of enterFrame to keep track of time. I know there are examples but this is just another one that might be helpful to a fellow solar 2d developer. It’s been influenced by older posts a few years ago.
Simply copy and paste the code below and save it as main.lua to see it in action. It could be improved but it’s a good starter for somebody that might need this kind of functionality in their game / app. You can also modify the number of decimals / precision really easily.
local widget = require("widget")
local prevFrameTime, currentFrameTime
local deltaFrameTime = 0
local totalTime = 0
local timeAtPause = 0
local lengthOfPause = 0
local totalPauseTime = 0
local pauseButton
local resumeButton
local resetButton
local startButton
local DECIMAL_PLACES = 3
local title = display.newText( "Example stop watch using enterFrame", 0, 0, native.systemFont, 35 )
title.x = display.contentCenterX
title.y = display.contentCenterY - 200
local txt_counter = display.newText( totalTime, 0, 0, native.systemFont, 55 )
txt_counter.x = display.contentCenterX
txt_counter.y = title.y + 100
txt_counter:setTextColor( 255, 255, 255 )
local function enterFrame(e)
local currentFrameTime
currentFrameTime = system.getTimer() - totalPauseTime
if prevFrameTime then
--calculate how many milliseconds since last frame
deltaFrameTime = currentFrameTime - prevFrameTime
end
prevFrameTime = currentFrameTime
--this is the total time in milliseconds
totalTime = totalTime + deltaFrameTime
txt_counter.text = string.format("%." .. DECIMAL_PLACES .. "f",(totalTime * 0.001))
end
Runtime:addEventListener( "enterFrame", enterFrame )
local function pauseStopWatch(event)
if (event.phase == "ended") then
Runtime:removeEventListener("enterFrame",enterFrame)
timeAtPause = system.getTimer()
resumeButton:setEnabled(true)
pauseButton:setEnabled(false)
end
end
local function resumeStopWatch(event)
if (event.phase == "ended") then
Runtime:addEventListener( "enterFrame", enterFrame )
lengthOfPause = system.getTimer() - timeAtPause
totalPauseTime = totalPauseTime + lengthOfPause
resumeButton:setEnabled(false)
pauseButton:setEnabled(true)
end
end
local function resetStopWatch(event)
if (event.phase == "ended") then
Runtime:removeEventListener("enterFrame",enterFrame)
txt_counter.text = string.format("%." .. DECIMAL_PLACES .. "f", 0)
startButton:setEnabled(true)
pauseButton:setEnabled(false)
resumeButton:setEnabled(false)
end
end
local function startStopWatch(event)
if (event.phase == "ended") then
prevFrameTime, currentFrameTime = nil
deltaFrameTime = 0
totalTime = 0
timeAtPause = 0
lengthOfPause = 0
totalPauseTime = 0
Runtime:addEventListener( "enterFrame", enterFrame )
startButton:setEnabled(false)
pauseButton:setEnabled(true)
end
end
pauseButton = widget.newButton(
{
left = 100,
top = 200,
id = "button1",
label = "Pause",
onEvent = pauseStopWatch,
fontSize = 40
}
)
pauseButton.x = display.contentCenterX - 100
pauseButton.y = txt_counter.y + 100
resumeButton = widget.newButton(
{
left = 100,
top = 200,
id = "button1",
label = "Resume",
onEvent = resumeStopWatch,
fontSize = 40
}
)
resumeButton.x = display.contentCenterX + 100
resumeButton.y = pauseButton.y
resetButton = widget.newButton(
{
left = 100,
top = 200,
id = "button1",
label = "Reset",
onEvent = resetStopWatch,
fontSize = 40
}
)
resetButton.x = pauseButton.x
resetButton.y = pauseButton.y + 100
startButton = widget.newButton(
{
left = 100,
top = 200,
id = "button1",
label = "Start",
onEvent = startStopWatch,
fontSize = 40
}
)
startButton.x = resumeButton.x
startButton.y = resetButton.y
resumeButton:setEnabled(false)
startButton:setEnabled(false)