lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 02.02.2013 3:33, Peter Slížik wrote:
How would one rewrite these examples with coroutines? I mean, if I replace the sleep() in the former example with a yield, how would I get correct timing? Or is this example completely inadequate?]

Something like this:

function sleep(ms)
    local co = coroutine.running()
setInterval(ms, function() coroutine.resume(co) end) -- like a timer, but only runs once
    coroutine.yield()
end

function SpawnRabbit()
    coroutine.resume(coroutine.create(function()
        local y = 100; // rabbit's y-coordinate, some constant value
        for x = start_position to carrot_position {
          draw_rabbit(x, y);
          sleep(100ms);
        }
    end))
end

Notice the code from 1st example went there unchanged, but now it would work for any number of rabbits. Your 2nd example is directly event-based, this is the coroutine-less approach. Imagine if you need to first move the rabbit right, then down, then left. With coroutines you'll write 3 consecutive loops, while in explicit event implementation you'll need to maintain state (going right, down or left).

Here's also an example from Knytt Stories Ex (my mod for a great platformer) - a title cutscene animation:

    local Delay = coroutine.yieldN  -- calls yield N times

Timer(1, coroutine.wrap(function() -- the timer is triggered every tick
        -- fade in picture
        for i = 126, 0, -2 do
            pic:SetTransparency(i)
            Delay(1)
        end
        -- move picture
        while pic:GetY() < MaxY do
            pic:SetY(pic:GetY() + 1)
            Delay(2)
        end
        -- fade in "Extended Version" text
        for i = 127, 0, -1 do
            text:SetTransparency(i)
            Delay(1)
        end
        -- done, remove timer
        RemoveTimer()
    end))


--
Best regards,
Sergey Rozhenko                 mailto:sergroj@mail.ru