Thursday, September 10, 2015

Implementing Circular Countdown Timer with Corona SDK

As part of Today Resolution, I implemented a countdown timer, which I think will be useful in other projects, so I decided to share it here.  But first, this is how it looks.


Now the code


CircularCountdown = {}

local rad = math.rad
local sin = math.sin
local cos = math.cos
local abs = math.abs


CircularCountdown.newCircularCountdown = function(radius, second, callback)
    local _ring = display.newGroup()
    local _ticks = {}
    local _timer = second
    local _label
    local _thandle
    
    
    for i=180-6,-180,-6 do
        local rd = rad(i)
        local sinrd = sin(rd)
        local cosrd = cos(rd)        
        
        local c = display.newRect(sinrd * radius, cosrd * radius, 4, 10)
        c.rotation = -i
        c:setFillColor(0, 0, 0, 0.2)
        _ring:insert(c)
        _ticks[#_ticks + 1] = c
    end
    
    _label = display.newText(""..second, 0, 0, native.systemFont, 96)
    _label:setFillColor(0.3, 0.3, 0.3)
    _ring:insert(_label)
    
        
    local timeStamp, now, dt
    local ms = 0
    local interval
    local i = 0
    
    local sec = 0
    local function update()
        now = system.getTimer()
        dt = now - timeStamp
        timeStamp = now
        
        ms = ms + dt
        if ms > interval then
            i = i + 1
            if _ticks[i] then
                _ticks[i]:setFillColor(0, 0, 0)
            end
            ms = ms - interval
        end
        
        sec = sec + dt
        if sec > 1000 then
            _timer = _timer - 1
            _label.text = "" .. _timer
            callback(_ring, _timer)
            if _timer == 0 then
                Runtime:removeEventListener("enterFrame", update)
            end
            sec = sec - 1000
        end
    end
    
    function _ring:start()
        interval = (second * 1000) / #_ticks
        timeStamp = system.getTimer()
        Runtime:addEventListener("enterFrame", update)
    end
        
    
    return _ring
end


The three parameters, radius, second, and callback are radius of the countdown circle, the second to countdown, and a callback function.  The callback function will be called every second.

Note that the number of second must be at least 2.

This is how I use it.



local cirCountdown = CircularCountdown.newCircularCountdown(100, 5, onCountdown)
cirCountdown.x = display.contentCenterX
cirCountdown.y = display.contentCenterY
cirCountdown:start()

 You can fiind the working demo project at https://github.com/uchat/circularCountdown

No comments:

Post a Comment