Timer iOS cycle implementation

Hi Everyone…

I am trying to do a simple task, but I got stuck on the third step.

I have 3 objects; obj1, obj2, obj3

I am adding an Event Listener to all 3

I have only the 1st one Visible --> obj1.isVisible = true

I touch obj1 … obj1.isVisible = false … obj1 gives me 1 point

I see NO objects…

…after 20 seconds I can see obj2 --> obj2.isVisible = true

Now I have only the 2nd one Visible --> obj2.isVisible = true

I touch obj2 … obj2.isVisible = false … obj2 gives me 1 point … now I have 2 points

now I see NO objects…

…after 20 seconds I can see obj3 --> obj3.isVisible = true

Now I have only the 3nd one Visible --> obj3.isVisible = true

I touch obj3 … obj3.isVisible = false … obj3 gives me 1 point … now I have 3 points

now I see NO objects…

PROBLEM…

I am expecting that after 20 seconds I can see obj1 visible again…

but nothing happens I don’t see the object 1 after 20 hours…

I am just trying to make a loop on those three objects, like after obj3

shows obj1, star ll over again, like that.

I hope this make sense and somebody can get me an idea in how to do this.

If you want I can post my code…

Thanks for all your help and all your time

Victor

How about creating a table of objects, and iterating over it in your timer function.  Something like:

--Create a table to hold all the objects local objs={} --Create objects and add them to table local objs[1] = display.newRect(...) local objs[2] = display.newRect(...) local objs[3] = display.newRect(...) --Make objects 2 and 3 invisible objs[2].isVisible=false objs[3].isVisible=false --Counter to indicate which object is currently visible local visibleObject=1 --Timer function. Makes the current object invisible, and the next object visible. local function updateObject()   --Make the current object invisible    objs[visibleObject].isVisible=false    --Bump the visible object counter    visibleObject=visibleObject+1 --Don't overflow    if (visibleObject==4) then visibleObject=1 end --Make the next object visible    objs[visibleObject].isVisible=true end --Call the timer function every 1s forever timer.performWithDelay(1000, updateObject, -1)

When I run your code…

I see circle 1 … then after the timer,

1 is gone!! I see 2 … after the timer

2 is gone!! I see 3 … after the timer

3 is gone!! I see 1 …

Works GREAT!!!

but in my code when I touch object 1 with no timer

the object is waiting for me to touch it…

1 is fine

2 is fine

3 PROBLEMS!!!..

Why I can not pass the last object?

This is my function

    --Create a table to hold all the objects     local objs={}          function objsListener( event )            if event.phase == "began" then             if ( event.target.id ) == 1 then                 print("1")                 -- obj 1 is gone!                 objs[1].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    objs[visibleObject].isVisible=true                elseif ( event.target.id ) == 2 then                 print("2")                 -- obj 2 is gone!                 objs[2].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    objs[visibleObject].isVisible=true                elseif ( event.target.id ) == 3 then                 print("3")                 -- obj 3 is gone!                 objs[3].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    objs[visibleObject].isVisible=true               end         return true                     end     end

What is wrong?

I think you’ll throw an error when you get to the third object, because:

  • you reach the line - elseif ( event.target.id ) == 3 then
  • then you make the third object invisible 
  • then you bump the object counter (which will then equal 4)
  • then you try to make the fourth object invisible…
  • … but there isn’t a fourth object - so an error will be thrown, and the function is stopped prematurely (meaning the rest of the function is never executed)

Good, now it works fine…thanks. with a simple 3 dots.

Now when I try that in MY real code, actually using the waiting time…

PROBLEMS!!! This is giving me headaches…

Sorry the code is long but please help me out.

The Last function is the one we are working on

just scrol down to the end…

(I put all of them just in case)


I have a normal function to add score or life

    function addToLife()         lifeTxt.isVisible = true         life = archivo.datos.life         life = life + 1         archivo.datos.life  = life         archivo:guarda()         lifeTxt.text = life     end

Now the function to waiting period…

    function collectLife()         local lifeDuration = os.time()         local function waitingLife()             local nowGetLife = os.time()                 if ( nowGetLife \> lifeDuration + 5 ) then                           cofre[visibleObject].isVisible = true                 end         end         lifeTimer = timer.performWithDelay(20000, waitingLife)     end

then a little function to tell me that the little diamon (diamantito) got to his place

    function yaLlego()         diamantito.isVisible = false     end

Now for the diamond to move to the center of the screen

    function juntaVidita()         transition.to(diamantito, {             time=10,             x = display.contentCenterX + 2000,             y = display.contentCenterY - 1020,             xScale = .3,             yScale = .3,             rotation = 0,             alpha = 0,             onComplete = yaLlego             })     end

this is to make the objects dissapear – cofre is the object

function vidita()         diamantito.alpha = 1         diamantito.isVisible = true         transition.to(diamantito, {             time=1500,             x = display.contentCenterX,             y = display.contentCenterY,             xScale = 2,             yScale = 2,             rotation = 130,             transition = easing.inSine,             --alpha = 0,             onComplete = juntaVidita             })                          if (viditaRound == 1) then                 transition.to(cofre[1], {                     time=200,                     xScale = 0.01,                     yScale = 0.01,                     alpha = 0                 })                 viditaRound = 2             elseif (viditaRound == 2) then                 transition.to(cofre[2], {                     time=200,                     xScale = 0.01,                     yScale = 0.01,                     alpha = 0                 })                 viditaRound = 3             elseif (viditaRound == 3) then                 transition.to(cofre[3], {                     time=200,                     xScale = 0.01,                     yScale = 0.01,                     alpha = 0                 })                 viditaRound = 4             else             return true             end                          addToLife()             collectLife()     end

And finally here is the function that will make the magic…

function cofreListener( event )            if event.phase == "began" then             if ( event.target.id ) == 1 then                 -- obj 1 is gone!                 cofre[1].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    cofre[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    --cofre[visibleObject].isVisible=true                 diamantito.x = cofre[1].x                 diamantito.y = cofre[1].y                 plus1.x = cofre[1].x                 plus1.y = cofre[1].y                 if (viditaRound == 1) then                     vidita()                 end                elseif ( event.target.id ) == 2 then                                                         print("2")                 -- obj 2 is gone!                 cofre[2].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    cofre[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    --cofre[visibleObject].isVisible=true                 diamantito.x = cofre[2].x                 diamantito.y = cofre[2].y                 plus1.x = cofre[2].x                 plus1.y = cofre[2].y                 if (viditaRound == 2) then                     vidita()                 end                elseif ( event.target.id ) == 3 then                                                                 print("3")                 -- obj 3 is gone!                 cofre[3].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    --objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    --cofre[visibleObject].isVisible=true                 diamantito.x = cofre[3].x                 diamantito.y = cofre[3].y                 plus1.x = cofre[3].x                 plus1.y = cofre[3].y                 if (viditaRound == 3) then                     vidita()                 end               end         return true                     end     end

Sorry I have no other way to do this… I guess it should be an easier way

or faster or better, but this is all I know…

Thanks a lot for your help

Victor

Hi Victor,

Sometimes when you’re figuring this stuff help, it can help to grab a scrap piece of paper and manually execute the code on the page.  ie. draw three ‘objects’ on the page, and write ‘isVisible’ in each.  Also add a separate variable for ‘visibleObject’ somewhere on the page.  Jot next to each variable what its initial value is.  Now execute the program by hand, slowly following the steps the computer will take, crossing out and writing new variable values on the page as you go.  It’ll help you see where there are any errors in the logic.

I think, in your loop, your getting some of the isVisible settings out of sequence.

In your cofreListener function, for each object you need to:

  • make the current object invisible
  • bump the counter (and wrap if necessary)
  • make the next object visible

In your code, this is out of sequence.  What your code does is:

  • make the current object invisible  (fine)
  • bump the counter (fine)
  • make the next object invisible - if the counter currently exceeds the table limit, you’ll be trying to make a non-object (or nil object) invisible, causing an error to be thrown and execution will halt
  • wrap counter if necessary (too late - may never be reached)

You can also save a lot of code by using event.target.id to your advantage.  Rather than hard coding event.target==“1”, event.target==“2”.  Your cofreListener function would look something like this:

if event.phase == "began" then --Get the object (based on the target ID, rather than hard coding to 1,2,3) local obj = cofre[event.target.id] --Make it disappear obj.isVisible=false --Bump counter visibleObject = visibleObject+1 --Now check for overflow, otherwise you may try to make a nil object visible / invisible if (visibleObject==4) then visibleObject=1 end --Get the next object to work on local next = cofre[visibleObject] --Make the next object visible next.isVisible=true --Don't know what this does, but use event.target.id so you don't have to hard code everything --These lines seem to relate to the next object diamantito.x = next.x diamantito.y = next.y --These lines seem to relate to the previous object plus1.x = obj.x plus1.y = obj.y --These lines seem to call function vidita when viditaRound is the same as event.target.id if (viditaRound == event.target.id) then     vidita() end return true end

Hope that helps.  Don’t guarantee this code will be perfectly as is - it’s just there as a demonstration.

You are helping me a lot… thanks…

I still don’t have it working the way I want…

I will put more time this weekend…

But the

  --Get the object (based on the target ID, rather than hard coding to 1,2,3)
  local obj = cofre[event.target.id]

Helped me a lot, I didn’t know this…

also the “paper” idea… I will do that, line by line thinking the logic I need

Thanks for all your help, I will let you know If I got it to work…

Cool - good luck  :slight_smile:

How about creating a table of objects, and iterating over it in your timer function.  Something like:

--Create a table to hold all the objects local objs={} --Create objects and add them to table local objs[1] = display.newRect(...) local objs[2] = display.newRect(...) local objs[3] = display.newRect(...) --Make objects 2 and 3 invisible objs[2].isVisible=false objs[3].isVisible=false --Counter to indicate which object is currently visible local visibleObject=1 --Timer function. Makes the current object invisible, and the next object visible. local function updateObject()   --Make the current object invisible    objs[visibleObject].isVisible=false    --Bump the visible object counter    visibleObject=visibleObject+1 --Don't overflow    if (visibleObject==4) then visibleObject=1 end --Make the next object visible    objs[visibleObject].isVisible=true end --Call the timer function every 1s forever timer.performWithDelay(1000, updateObject, -1)

When I run your code…

I see circle 1 … then after the timer,

1 is gone!! I see 2 … after the timer

2 is gone!! I see 3 … after the timer

3 is gone!! I see 1 …

Works GREAT!!!

but in my code when I touch object 1 with no timer

the object is waiting for me to touch it…

1 is fine

2 is fine

3 PROBLEMS!!!..

Why I can not pass the last object?

This is my function

    --Create a table to hold all the objects     local objs={}          function objsListener( event )            if event.phase == "began" then             if ( event.target.id ) == 1 then                 print("1")                 -- obj 1 is gone!                 objs[1].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    objs[visibleObject].isVisible=true                elseif ( event.target.id ) == 2 then                 print("2")                 -- obj 2 is gone!                 objs[2].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    objs[visibleObject].isVisible=true                elseif ( event.target.id ) == 3 then                 print("3")                 -- obj 3 is gone!                 objs[3].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    objs[visibleObject].isVisible=true               end         return true                     end     end

What is wrong?

I think you’ll throw an error when you get to the third object, because:

  • you reach the line - elseif ( event.target.id ) == 3 then
  • then you make the third object invisible 
  • then you bump the object counter (which will then equal 4)
  • then you try to make the fourth object invisible…
  • … but there isn’t a fourth object - so an error will be thrown, and the function is stopped prematurely (meaning the rest of the function is never executed)

Good, now it works fine…thanks. with a simple 3 dots.

Now when I try that in MY real code, actually using the waiting time…

PROBLEMS!!! This is giving me headaches…

Sorry the code is long but please help me out.

The Last function is the one we are working on

just scrol down to the end…

(I put all of them just in case)


I have a normal function to add score or life

    function addToLife()         lifeTxt.isVisible = true         life = archivo.datos.life         life = life + 1         archivo.datos.life  = life         archivo:guarda()         lifeTxt.text = life     end

Now the function to waiting period…

    function collectLife()         local lifeDuration = os.time()         local function waitingLife()             local nowGetLife = os.time()                 if ( nowGetLife \> lifeDuration + 5 ) then                           cofre[visibleObject].isVisible = true                 end         end         lifeTimer = timer.performWithDelay(20000, waitingLife)     end

then a little function to tell me that the little diamon (diamantito) got to his place

    function yaLlego()         diamantito.isVisible = false     end

Now for the diamond to move to the center of the screen

    function juntaVidita()         transition.to(diamantito, {             time=10,             x = display.contentCenterX + 2000,             y = display.contentCenterY - 1020,             xScale = .3,             yScale = .3,             rotation = 0,             alpha = 0,             onComplete = yaLlego             })     end

this is to make the objects dissapear – cofre is the object

function vidita()         diamantito.alpha = 1         diamantito.isVisible = true         transition.to(diamantito, {             time=1500,             x = display.contentCenterX,             y = display.contentCenterY,             xScale = 2,             yScale = 2,             rotation = 130,             transition = easing.inSine,             --alpha = 0,             onComplete = juntaVidita             })                          if (viditaRound == 1) then                 transition.to(cofre[1], {                     time=200,                     xScale = 0.01,                     yScale = 0.01,                     alpha = 0                 })                 viditaRound = 2             elseif (viditaRound == 2) then                 transition.to(cofre[2], {                     time=200,                     xScale = 0.01,                     yScale = 0.01,                     alpha = 0                 })                 viditaRound = 3             elseif (viditaRound == 3) then                 transition.to(cofre[3], {                     time=200,                     xScale = 0.01,                     yScale = 0.01,                     alpha = 0                 })                 viditaRound = 4             else             return true             end                          addToLife()             collectLife()     end

And finally here is the function that will make the magic…

function cofreListener( event )            if event.phase == "began" then             if ( event.target.id ) == 1 then                 -- obj 1 is gone!                 cofre[1].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    cofre[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    --cofre[visibleObject].isVisible=true                 diamantito.x = cofre[1].x                 diamantito.y = cofre[1].y                 plus1.x = cofre[1].x                 plus1.y = cofre[1].y                 if (viditaRound == 1) then                     vidita()                 end                elseif ( event.target.id ) == 2 then                                                         print("2")                 -- obj 2 is gone!                 cofre[2].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    cofre[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    --cofre[visibleObject].isVisible=true                 diamantito.x = cofre[2].x                 diamantito.y = cofre[2].y                 plus1.x = cofre[2].x                 plus1.y = cofre[2].y                 if (viditaRound == 2) then                     vidita()                 end                elseif ( event.target.id ) == 3 then                                                                 print("3")                 -- obj 3 is gone!                 cofre[3].isVisible = false                 --Bump the visible object counter                    visibleObject=visibleObject+1                    --Make the current object invisible                    --objs[visibleObject].isVisible=false                    --Don't overflow                    if (visibleObject==4) then visibleObject=1 end                    --Make the next object visible                    --cofre[visibleObject].isVisible=true                 diamantito.x = cofre[3].x                 diamantito.y = cofre[3].y                 plus1.x = cofre[3].x                 plus1.y = cofre[3].y                 if (viditaRound == 3) then                     vidita()                 end               end         return true                     end     end

Sorry I have no other way to do this… I guess it should be an easier way

or faster or better, but this is all I know…

Thanks a lot for your help

Victor

Hi Victor,

Sometimes when you’re figuring this stuff help, it can help to grab a scrap piece of paper and manually execute the code on the page.  ie. draw three ‘objects’ on the page, and write ‘isVisible’ in each.  Also add a separate variable for ‘visibleObject’ somewhere on the page.  Jot next to each variable what its initial value is.  Now execute the program by hand, slowly following the steps the computer will take, crossing out and writing new variable values on the page as you go.  It’ll help you see where there are any errors in the logic.

I think, in your loop, your getting some of the isVisible settings out of sequence.

In your cofreListener function, for each object you need to:

  • make the current object invisible
  • bump the counter (and wrap if necessary)
  • make the next object visible

In your code, this is out of sequence.  What your code does is:

  • make the current object invisible  (fine)
  • bump the counter (fine)
  • make the next object invisible - if the counter currently exceeds the table limit, you’ll be trying to make a non-object (or nil object) invisible, causing an error to be thrown and execution will halt
  • wrap counter if necessary (too late - may never be reached)

You can also save a lot of code by using event.target.id to your advantage.  Rather than hard coding event.target==“1”, event.target==“2”.  Your cofreListener function would look something like this:

if event.phase == "began" then --Get the object (based on the target ID, rather than hard coding to 1,2,3) local obj = cofre[event.target.id] --Make it disappear obj.isVisible=false --Bump counter visibleObject = visibleObject+1 --Now check for overflow, otherwise you may try to make a nil object visible / invisible if (visibleObject==4) then visibleObject=1 end --Get the next object to work on local next = cofre[visibleObject] --Make the next object visible next.isVisible=true --Don't know what this does, but use event.target.id so you don't have to hard code everything --These lines seem to relate to the next object diamantito.x = next.x diamantito.y = next.y --These lines seem to relate to the previous object plus1.x = obj.x plus1.y = obj.y --These lines seem to call function vidita when viditaRound is the same as event.target.id if (viditaRound == event.target.id) then     vidita() end return true end

Hope that helps.  Don’t guarantee this code will be perfectly as is - it’s just there as a demonstration.

You are helping me a lot… thanks…

I still don’t have it working the way I want…

I will put more time this weekend…

But the

  --Get the object (based on the target ID, rather than hard coding to 1,2,3)
  local obj = cofre[event.target.id]

Helped me a lot, I didn’t know this…

also the “paper” idea… I will do that, line by line thinking the logic I need

Thanks for all your help, I will let you know If I got it to work…

Cool - good luck  :slight_smile: