Sync multi objects using Transition.to API

Hi,

I am moving 3 objects from the top to down of the screen. I am using the transition.to API in order to achieve this effect. The 3 objects start from the same position Y=0.

The problem: The 3 object are not horizontal align (i.e. when the object moving down the screen the Y location of the 3 objects are not the same)

Is there a way that when using the transition.to I can Sync between the 3 objects?

Few notifications:

  1. A solution of grouping the 3 objects and transition the group is not feasible solution as these 3 objects are involved in collision (using the Physics engine) and as of that collision cannot be detected on different groups

  2. Don’t provide solution to replace the                 Transition.to to the form of manual movement by altering the X value of each object in the enterFrame event

  3. I have also put the transition.to lines immediately follow each one

 The code is something like this :

local object1 = display.newImageRect(params.group,params.image,iWidth,iHeight)

local object2 = display.newImageRect(params.group,params.image,iWidth,iHeight)
local object3 = display.newImageRect(params.group,params.image,iWidth,iHeight)

 object1.y =0; object2.y =0; object3.y =0
 

transition.to(Object1,{PARAMETERs… ,
                        onStart = function()
                                – Do something                                           
                        end ,
                        onComplete = function(obj)                                                                                                                                                – Do something
                        end } )

transition.to(Object2,{PARAMETERs… ,
                        onStart = function()
                                – Do something                                           
                        end ,
                        onComplete = function(obj)                                                                                                                                                     – Do something
                        end } )

transition.to(Object3,{PARAMETERs… ,
                        onStart = function()
                                – Do something                                           
                        end ,
                        onComplete = function(obj)                                                                                                                                                     – Do something
                        end } )

Thanks

   Yuval

Are the objects the same size?

Only the height are same- The width are different (randomly set)

Can this be achived in Corona - or Corona doesn’t support this with transition.to ?

If you have 3 objects that are the same height (.x and .y are based on the center of the object), then three transitions running at the same time should have them within one pixel of each other as it moves them.

Perhaps if you shared some code that might help us understand what you’re doing.  We have no idea what your parameters are you’re using.  Also code in your onStart() could inject delays too.

The other thing you can do if they all have to move together is to insert them into a display.newGroup() and run one transition on the whole group to move them.

Rob

Hi,

First regarding your last suggestion about adding the 3 objects into one group it is not doable as these 3 objects interact with collision (and per corona document cannot handle collision where they are on different groups)

Also I am attaching below part of the code (the relevant one) - I cannot provide all code as it is huge projects…I hope it is clear…

local function mainFrameLoop(event)

    --==============================================================

    --====== This is the main loop game execute at each frame rate

    --==============================================================      

    

    local function getNextPoolEnemyObject()

        – Get the next avalable object from Enemy pool

        currenEnemyIndexObject = currenEnemyIndexObject + 1 

        if currenEnemyIndexObject > MAX_ENEMY_ONSCREEN then currenEnemyIndexObject=1 end

        local object = spawnEnemyArr[currenEnemyIndexObject]        

        return object

    end

 if gameCoreVar.gamePhase == PHASE_STARTED then              

        gameCoreVar.distanceDG.text = gameCoreVar.distanceDG.text +1  

        if getNextEnemy then

            if shapeCount ==0 then

                getNextEnemyIndex = getNextEnemyIndex +1        

                shapeCount = enemyShapeArray[getNextEnemyIndex].count-1

            else

                shapeCount = shapeCount -1 

            end

            local enemyShapeRow = enemyShapeArray[getNextEnemyIndex]

            local randomEnemyShape =  enemyShapeArray[getNextEnemyIndex].shapeType[random(1,#enemyShapeRow.shapeType)] 

    

    – MOR CODE HERE…

    – Code …

    – Code …

    – Code …

     

     elseif randomEnemyShape == TWO_TUNNEL or randomEnemyShape == COLOR_TWO_TUNNEL then

            --====================================================== Handle TWO_TUNNEL Enemy =================================================================================                    

                local spaceBoxRand = random(enemyShapeRow.minSpaceBoxes_2tunnel,enemyShapeRow.maxSpaceBoxes_2tunnel)

                local boxHieghtRand = random( enemyShapeRow.minHeight, enemyShapeRow.maxHeight )

                local midBoxWidth = random(SHIP_SIZE*0.3 , _W - 2 * spaceBoxRand - 0.6 * SHIP_SIZE)

                local edgeBoxWidth = (_W - midBoxWidth - 2 * spaceBoxRand) * 0.5 – width of the right and left boxes                

                

                local boxRightImg = getNextPoolEnemyObject()

                boxRightImg.width = edgeBoxWidth; boxRightImg.height = boxHieghtRand

                local bridgeRightImg

                local bridgeLeftImg

                boxRightImg.y = -boxHieghtRand*0.5

                boxRightImg.x = _W - edgeBoxWidth * 0.5 

                boxRightImg:toBack()                

                boxRightImg.objName =  “twoTunnelEnemy”

                

                

                local boxLeftImg = getNextPoolEnemyObject()

                boxLeftImg.width = edgeBoxWidth; boxLeftImg.height = boxHieghtRand

                boxLeftImg.y = -boxHieghtRand*0.5

                boxLeftImg.x = edgeBoxWidth * 0.5 

                boxLeftImg:toBack()                

                boxLeftImg.objName =  “twoTunnelEnemy”

                

                local boxMidImg = getNextPoolEnemyObject()

                boxMidImg.width = midBoxWidth ;boxMidImg.height = boxHieghtRand

                boxMidImg.y = -boxHieghtRand*0.5

                boxMidImg.x = _W * 0.5 

                boxMidImg:toBack()                

                boxMidImg.objName =  “twoTunnelEnemy”

                getNextEnemy = false   

                physics.addBody( boxRightImg,“dynamic”, {isSensor=true  } )

                physics.addBody( boxLeftImg,“dynamic”, { isSensor=true } )

                physics.addBody( boxMidImg,“dynamic”, {  isSensor=true  } )    

                local delayTime = MOVMENT_ENEMY_FACTOR*(previousEnemyHieght + random( enemyShapeRow.minPointDelay,enemyShapeRow.maxPointDelay) + SHIP_SIZE*MIN_SPACE_ENEMY_FACTOR)                                

                

                transition.to(boxRightImg,{delay =delayTime , time= MOVMENT_ENEMY_FACTOR *  (_H + boxHieghtRand) , y=_H + boxHieghtRand * 0.5 , 

                        onComplete = function(obj)

                            physics.removeBody(obj)                             

                        end                           

                        } )           

                transition.to(boxLeftImg,{delay =delayTime , time= MOVMENT_ENEMY_FACTOR *  (_H + boxHieghtRand) , y=_H + boxHieghtRand * 0.5 , 

                        onStart = function(obj)  

                            obj.y = boxRightImg.y  --to sync so both shapes will start from the same y location - BUT SEEMS THAT IT IS NOT WORKING

                        end ,

                        onComplete = function(obj)                                                                      

                            physics.removeBody(obj)                        

                        end 

                        } )                          

                transition.to(boxMidImg,{delay =delayTime , time= MOVMENT_ENEMY_FACTOR *  (_H + boxHieghtRand) , y=_H + boxHieghtRand * 0.5 , 

                        onStart = function(obj)  

                            obj.y = boxRightImg.y  --to sync so both shapes will start from the same y location - BUT SEEMS THAT IT IS NOT WORKING

                            getNextEnemy = true;

                        end ,

                        onComplete = function(obj) 

                            physics.removeBody(obj)                                                                                                 

                        end 

                        } )                          

                

                previousEnemyHieght = boxHieghtRand

            end          

Hi Yuval,

Please try assigning a “tag” to all 3 transitions, then start all 3 transitions but immediately pause() them using the tag value. Then, after the desired delay time, resume() transitions based on that tag.

Brent

I am trying to implement this solution but it seems that the creating few transition with the same tag has some problem. After a lot of work I was able to identify the problem which seems Corona bug (or mine).

Please refer to the below code. The resume does not work !!
I would have expected that the 2 boxes will move to Y=0 but nothing happened - The 2 Boxes remain at the same spot and not moved to Y=500.

What am I missing here?

local box1 = display.newRect( 100, 100, 50, 50 )
local box2 = display.newRect( 200, 100, 50, 50 )
transition.to( box1, {time= 2000,y=500,tag=“abc”} )
transition.to( box2, {time= 2000,y=500,tag=“abc”} )
transition.pause( “abc”)
transition.resume(“abc”)

Sorry I ment to say that :

"I would have expected that the 2 boxes will move to Y=500 but nothing happened - The 2 Boxes remain at the same spot and not moved to Y=500.

Hi @yuval_forish

As Brent mentioned, try resume your timer after desired delay time otherwise it will not work.

Instead of

  transition.resume(“abc”)

use this,

 timer.performWithDelay( 100, function() transition.resume(“abc”); end)

Good Luck!

burhan

Thanks,

the resume with delay works but the original problem stil exist  (i.e. the objects are not allign) 

Are the objects the same size?

Only the height are same- The width are different (randomly set)

Can this be achived in Corona - or Corona doesn’t support this with transition.to ?

If you have 3 objects that are the same height (.x and .y are based on the center of the object), then three transitions running at the same time should have them within one pixel of each other as it moves them.

Perhaps if you shared some code that might help us understand what you’re doing.  We have no idea what your parameters are you’re using.  Also code in your onStart() could inject delays too.

The other thing you can do if they all have to move together is to insert them into a display.newGroup() and run one transition on the whole group to move them.

Rob

Hi,

First regarding your last suggestion about adding the 3 objects into one group it is not doable as these 3 objects interact with collision (and per corona document cannot handle collision where they are on different groups)

Also I am attaching below part of the code (the relevant one) - I cannot provide all code as it is huge projects…I hope it is clear…

local function mainFrameLoop(event)

    --==============================================================

    --====== This is the main loop game execute at each frame rate

    --==============================================================      

    

    local function getNextPoolEnemyObject()

        – Get the next avalable object from Enemy pool

        currenEnemyIndexObject = currenEnemyIndexObject + 1 

        if currenEnemyIndexObject > MAX_ENEMY_ONSCREEN then currenEnemyIndexObject=1 end

        local object = spawnEnemyArr[currenEnemyIndexObject]        

        return object

    end

 if gameCoreVar.gamePhase == PHASE_STARTED then              

        gameCoreVar.distanceDG.text = gameCoreVar.distanceDG.text +1  

        if getNextEnemy then

            if shapeCount ==0 then

                getNextEnemyIndex = getNextEnemyIndex +1        

                shapeCount = enemyShapeArray[getNextEnemyIndex].count-1

            else

                shapeCount = shapeCount -1 

            end

            local enemyShapeRow = enemyShapeArray[getNextEnemyIndex]

            local randomEnemyShape =  enemyShapeArray[getNextEnemyIndex].shapeType[random(1,#enemyShapeRow.shapeType)] 

    

    – MOR CODE HERE…

    – Code …

    – Code …

    – Code …

     

     elseif randomEnemyShape == TWO_TUNNEL or randomEnemyShape == COLOR_TWO_TUNNEL then

            --====================================================== Handle TWO_TUNNEL Enemy =================================================================================                    

                local spaceBoxRand = random(enemyShapeRow.minSpaceBoxes_2tunnel,enemyShapeRow.maxSpaceBoxes_2tunnel)

                local boxHieghtRand = random( enemyShapeRow.minHeight, enemyShapeRow.maxHeight )

                local midBoxWidth = random(SHIP_SIZE*0.3 , _W - 2 * spaceBoxRand - 0.6 * SHIP_SIZE)

                local edgeBoxWidth = (_W - midBoxWidth - 2 * spaceBoxRand) * 0.5 – width of the right and left boxes                

                

                local boxRightImg = getNextPoolEnemyObject()

                boxRightImg.width = edgeBoxWidth; boxRightImg.height = boxHieghtRand

                local bridgeRightImg

                local bridgeLeftImg

                boxRightImg.y = -boxHieghtRand*0.5

                boxRightImg.x = _W - edgeBoxWidth * 0.5 

                boxRightImg:toBack()                

                boxRightImg.objName =  “twoTunnelEnemy”

                

                

                local boxLeftImg = getNextPoolEnemyObject()

                boxLeftImg.width = edgeBoxWidth; boxLeftImg.height = boxHieghtRand

                boxLeftImg.y = -boxHieghtRand*0.5

                boxLeftImg.x = edgeBoxWidth * 0.5 

                boxLeftImg:toBack()                

                boxLeftImg.objName =  “twoTunnelEnemy”

                

                local boxMidImg = getNextPoolEnemyObject()

                boxMidImg.width = midBoxWidth ;boxMidImg.height = boxHieghtRand

                boxMidImg.y = -boxHieghtRand*0.5

                boxMidImg.x = _W * 0.5 

                boxMidImg:toBack()                

                boxMidImg.objName =  “twoTunnelEnemy”

                getNextEnemy = false   

                physics.addBody( boxRightImg,“dynamic”, {isSensor=true  } )

                physics.addBody( boxLeftImg,“dynamic”, { isSensor=true } )

                physics.addBody( boxMidImg,“dynamic”, {  isSensor=true  } )    

                local delayTime = MOVMENT_ENEMY_FACTOR*(previousEnemyHieght + random( enemyShapeRow.minPointDelay,enemyShapeRow.maxPointDelay) + SHIP_SIZE*MIN_SPACE_ENEMY_FACTOR)                                

                

                transition.to(boxRightImg,{delay =delayTime , time= MOVMENT_ENEMY_FACTOR *  (_H + boxHieghtRand) , y=_H + boxHieghtRand * 0.5 , 

                        onComplete = function(obj)

                            physics.removeBody(obj)                             

                        end                           

                        } )           

                transition.to(boxLeftImg,{delay =delayTime , time= MOVMENT_ENEMY_FACTOR *  (_H + boxHieghtRand) , y=_H + boxHieghtRand * 0.5 , 

                        onStart = function(obj)  

                            obj.y = boxRightImg.y  --to sync so both shapes will start from the same y location - BUT SEEMS THAT IT IS NOT WORKING

                        end ,

                        onComplete = function(obj)                                                                      

                            physics.removeBody(obj)                        

                        end 

                        } )                          

                transition.to(boxMidImg,{delay =delayTime , time= MOVMENT_ENEMY_FACTOR *  (_H + boxHieghtRand) , y=_H + boxHieghtRand * 0.5 , 

                        onStart = function(obj)  

                            obj.y = boxRightImg.y  --to sync so both shapes will start from the same y location - BUT SEEMS THAT IT IS NOT WORKING

                            getNextEnemy = true;

                        end ,

                        onComplete = function(obj) 

                            physics.removeBody(obj)                                                                                                 

                        end 

                        } )                          

                

                previousEnemyHieght = boxHieghtRand

            end          

Hi Yuval,

Please try assigning a “tag” to all 3 transitions, then start all 3 transitions but immediately pause() them using the tag value. Then, after the desired delay time, resume() transitions based on that tag.

Brent

I am trying to implement this solution but it seems that the creating few transition with the same tag has some problem. After a lot of work I was able to identify the problem which seems Corona bug (or mine).

Please refer to the below code. The resume does not work !!
I would have expected that the 2 boxes will move to Y=0 but nothing happened - The 2 Boxes remain at the same spot and not moved to Y=500.

What am I missing here?

local box1 = display.newRect( 100, 100, 50, 50 )
local box2 = display.newRect( 200, 100, 50, 50 )
transition.to( box1, {time= 2000,y=500,tag=“abc”} )
transition.to( box2, {time= 2000,y=500,tag=“abc”} )
transition.pause( “abc”)
transition.resume(“abc”)

Sorry I ment to say that :

"I would have expected that the 2 boxes will move to Y=500 but nothing happened - The 2 Boxes remain at the same spot and not moved to Y=500.

Hi @yuval_forish

As Brent mentioned, try resume your timer after desired delay time otherwise it will not work.

Instead of

  transition.resume(“abc”)

use this,

 timer.performWithDelay( 100, function() transition.resume(“abc”); end)

Good Luck!

burhan