Not quite getting tween.delay (Solved)

I’ve been lurking, and studying and playing and learning. Kudos to all the helpful folks here. I seem to have a mental block on tween.delay usage for timing. I was hoping to use it to time an ending sequence for a game level.

boomSequence - > ids of images on a tile sheet.

tileMap - > background tile map (holds ids of tile images)

I have 3 as a delay which is obviously absurd but the tiles change immediately.

This is called with endSequence(endx,endy,1)

Getting the animation to work other ways is not a problem but I thought this approach should work. Thanks.


boomSequence = {259,269,279,289,299,309,319,225}
    
function endSequence(x,y,index)
    tileMap[y-1][x-1] = boomSequence[index]
    tileMap[y][x-1] = boomSequence[index]
    tileMap[y+1][x-1] = boomSequence[index]
    tileMap[y-1][x] = boomSequence[index]
    tileMap[y][x] = boomSequence[index]
    tileMap[y+1][x] = boomSequence[index]
    tileMap[y-1][x+1] = boomSequence[index]
    tileMap[y][x+1] = boomSequence[index]
    tileMap[y+1][x+1] = boomSequence[index]
    if index < #boomSequence then
        tween.delay(3, endSequence(x,y,index + 1))
    end
end

EDIT: Interesting: found a post by Briarfox earlier today which led me to this which does work. I’d still love an explanation why the first does not work. (old brain cells) Thank you.

boomSequence = {259,269,279,289,299,309,319,225}
    
function endSequence(x,y,index)
    tileMap[y-1][x-1] = boomSequence[index]
    tileMap[y][x-1] = boomSequence[index]
    tileMap[y+1][x-1] = boomSequence[index]
    tileMap[y-1][x] = boomSequence[index]
    tileMap[y][x] = boomSequence[index]
    tileMap[y+1][x] = boomSequence[index]
    tileMap[y-1][x+1] = boomSequence[index]
    tileMap[y][x+1] = boomSequence[index]
    tileMap[y+1][x+1] = boomSequence[index]
    tween.delay(3, function() 
            if index < #boomSequence then 
                endSequence(x,y,index + 1)
            end 
        end)
end

In the first version you directly call the function endSequence, while in the second example you call it when the tween is complete.

You could do it like this also to not start an unneeded tween:

   if index < #boomSequence then
        tween.delay(3, function () endSequence(x,y,index + 1) end)
    end

@Pops - it is a bit tricky

in your version, you are actually trying to call the function, by adding brackets and parameters.

What tween.delay wants, however, is just the address of the function so it can call it later, ie it just wants the word endSequence (which holds the function address, not the function itself). Of course this doesn’t suit you, because you want to add some arguments as well.

Briarfox’s version writes a function as the callback. When you do it this way, it doesn’t get run straight away (which would fail for the same reason as your version). Instead, Lua creates the function, stores it away, and returns the address, which is what tween.delay wants. And because Briarfox’s version includes the arguments you wanted, it solves that problem too.

I’ve talked about it here

http://coolcodea.wordpress.com/2013/09/13/111-anonymous-functions-and-the-mysterious-_g/

Hope this helps. (Don’t give up on this stuff, I am in the same generation as you, probably, and I have learned a lot playing with Codea).

@Ignatz - tricky it is. I understand the whole memory address/pointer stuff. Good refresher link - thank you. I won’t give up. The problem is I’ve gotten to the point that for everything I learn I have to give something back :slight_smile: That’s why I have a “Hello your name is…” sticker on my bathroom mirror!

@tnlogy - good point

I really want to wrap my head around this so I went back to the drawing board. I changed the endSequence function to eliminate the parameters and it works like this.

function endSequence2()
    items[endy-1][endx-1] = boomSequence[endindex]
    items[endy][endx-1] = boomSequence[endindex]
    items[endy+1][endx-1] = boomSequence[endindex]
    items[endy-1][endx] = boomSequence[endindex]
    items[endy][endx] = boomSequence[endindex]
    items[endy+1][endx] = boomSequence[endindex]
    items[endy-1][endx+1] = boomSequence[endindex]
    items[endy][endx+1] = boomSequence[endindex]
    items[endy+1][endx+1] = boomSequence[endindex]
    if endindex < #boomSequence then
        endindex = endindex + 1
        tween.delay(.1, endSequence2)
    end
end

tnlogy’s change to my original , keeping the parameters but putting the check before the tween, makes the most sense (to me).

Is this unique to the tween.delay or does it apply to all callbacks?

Thank you both.

@pops - it applies to all callbacks, there’s nothing special about tweens.

This is more compact

for i=-1,1 do
    for j=-1,1 do
        items(endy+i,endx+j)=boomSequence(endindex)
    end
end

Also note that in Codea, all the functions take x before y, ie columns then rows, so it is good to get into the habit of doing the same thing with your tables, to avoid confusing yourself.

PS Why have a tween at all, if the delay is so small?

@Ignatz I’m still kinda approaching all this with a brute force mentality. I’ve already refactored things about a dozen times while learning Lua and Codea.

Don’t you mean y before x? I’ve spent forever using upper left to lower right drawing and the lower left origin is driving me nuts. I’m committed to retraining my brain but it constantly screws me up.

I decided to jump in with both feet and just let things happen. I’m recreating an old game I enjoyed from 1992 (S.C.Out) I’ve got all the original graphics and a DOSBox version of the game as reference. My approach is to get something to work and then refactor as I learn. It keeps my interest better than trying to learn everything and then apply it. I’m trying to balance getting things working with advancing my knowledge. Example: I know meshes are where I’ll end up but images and sprites work for now.

I have a level editor written in Xojo which allows me to get things done faster in a known environment. My gameplan (more or less) in no particular order:

1 - Define a basic data structure (done)
2 - Recreate level 1 (done)
3 - Create some dummy levels to introduce more advanced interaction (in process)
4 - Refine data structure to accommodate what I learn in #3
5 - Continue to add levels from original game
6 - Refactor, refactor, refactor

Of course there are constant diversions to your site and others to re-read and reinforce my journey. I’m sure I will have plenty of questions along the way. Hopefully I’ll be able to pay all the help forward down the road :slight_smile:

Why have the tween? The animation seemed too fast and when I researched delays here the tween approach seemed straight forward. As I move forward there will be a lot of short animations so I wanted to get an approach down.

@Pops - vectors are in the form (x,y), so are sprites, so are meshes, everything has x before y. Go with the flow!

Tweens are just simple timers. The main reason for using them is the special animation effects they offer, like endless looping. If you’re just using them as timers, I would just use your own timer, ie initialise timer=0, then increment in the draw function with timer=timer+DeltaTime, which adds the time slice since the last draw. Then just test if the timer exceeds a given value.