Search code examples
loopstimerluapositioncoronasdk

Lua / Corona SDK / Loop Spawning / Positional Difference / Framerate independent animation


So while building a mobile game with Corona SDK I have recently been facing a problem, that I couldn't solve, which are positional differences when spawning display objects in a loop. I got some help and found out this must have something to do with framerate independent animation. But now im facing this :

Albeit I'm using framerate independent animation here, this also produces the same problem. This gets emphasized by increasing the speed of the loop, as in the code below. What are your thoughts on this?

local loopSpeed =  306
local loopTimerSpeed = 1000
local gapTable = {}
local gapLoopTimer
local frameTime
local gap

--enterFrame for time only

    local function frameTime(event)

        frameTime = system.getTimer()

    end

--enterFrame

    local function enterFrame(self, event)

        local deltaTime = frameTime - self.time
        print(deltaTime/1000)
        self.time = frameTime
        local speed = self.rate * deltaTime / 1000
        self:translate(speed, 0)

    end

--loop speed function

local function setLoopSpeed(factor)

    loopSpeed = loopSpeed * factor
    loopTimerSpeed = loopTimerSpeed / factor

end

--set the loop speed

    setLoopSpeed(3)

--loop to create gaps

local function createGap()

    gap = display.newRect(1, 1, 308, 442)
    gap.time = system.getTimer()
    gap.anchorX = 1
    gap.anchorY = 0

    --animation

        gap.rate = loopSpeed
        gap.enterFrame = enterFrame
        Runtime:addEventListener("enterFrame", gap)

    --fill table for cleaning up

        table.insert(gapTable, gap)

    --cleaning up

        for i = #gapTable, 1, -1 do

            local thisGap = gapTable[i]

            if thisGap.x > display.contentWidth + 500 then

                display.remove(thisGap)
                table.remove(gapTable, i)
                Runtime:removeEventListener("enterFrame", thisGap)

            end

            thisGap = nil

        end

end

Runtime:addEventListener("enterFrame", frameTime)

gapLoopTimer = timer.performWithDelay(

    loopTimerSpeed,
    createGap,
    0

)

Solution

  • If you can set up size of gap between rects try use code below

    local gapTable = {}
    local gapWidth = 50
    local runtime = 0
    local speed = 20
    local gap
    
    local function getDeltaTime()
        local temp = system.getTimer()  -- Get current game time in ms
        local dt = (temp-runtime) / (1000/display.fps)  -- 60 fps or 30 fps as base
        runtime = temp  -- Store game time
        return dt
    end
    
    local function enterFrame()
        local dt = getDeltaTime()
    
        for i=1, #gapTable do
            gapTable[i]:translate(speed * dt, 0)
        end    
    end
    
    local function createGap()
        local startX = 0
    
        if #gapTable > 0 then
            startX = gapTable[#gapTable].x - gapWidth - gapTable[#gapTable].width
        end 
    
        gap = display.newRect(startX, 1, 308, 442)
        gap.anchorX, gap.anchorY = 1, 0
    
        table.insert(gapTable, gap)
    
        --cleaning up
        for i=#gapTable, 1, -1 do
            if gapTable[i].x > display.contentWidth + 500 then
                local rect = table.remove(gapTable, i)
    
                if rect ~= nil then
                    display.remove(rect)
                    rect = nil
                end    
            end
        end
    end
    
    timer.performWithDelay(100, createGap,  0)
    
    Runtime:addEventListener("enterFrame", enterFrame) 
    

    Hope this helps:)