Remove Unlinked Bubbles In Bubble Shooter Game?

Hi. I’m building a bubble shooter game. Everything is working fine.

However, I need to remove unlinked bubble. I made it work by checking all the bubble on the field. But when in endless mode, there are more than 30 bubbles, so the frame rate drops.

 

Anyone has the better logic or the way to remove the unlinked bubble more efficiently?

 

thank you.

You are probably going to have to provide more information or some code for people to be able to respond.

– check if it is the new connection or not

local function isNewConnection(row,col)
    val2 = getValue(row,col)
 
    local test = false
    if val2 and val2 ~= false and val2 ~= 0 then
        for i=0,#connArray,1 do
            if connArray[i] == row…col then
                test = true
            end
        end
        if  test == false then
            return true
        else
            return false
        end
    end
    
    return false
end

local count = 0

 

–get connections of the bubbles, and check other bubbles
local function getConnections(row2, col2,connArray2)
    
    – insert row col vao connArray
    table.insert(connArray2, row2…col2)
    
    local odd = row2%2
    
    count = count + 1
    for i=-1,1,1 do
        for j=-1,1,1 do
            
            if (i ~= 0) or (j~=0) then
                if i==0 or j==0 or (j==-1 and odd ==0) or (j==1 and odd==1) then
                    if (isNewConnection(row2+i, col2+j)) then

–if the bubbles row is 0, it means they are connected
                        if row2+i == 0  then
                            connArray2[0] = “connected”
                        else

–if not, continue to check
                                getConnections(row2+i, col2+j,connArray2)
                        end
                    end
                end
            end
        end
    end
end

 

–remove all except connected bubbles
local function removeNotConnected()
    local idx = 0     for i = 1, #gemsTable,1 do
        for j = 0, 7,1 do
            if gemsTable[i][j] and gemsTable[i][j] ~=0 and gemsTable[i][j] ~= nil then
               
                connArray = {}
                getConnections(i,j,connArray)
                if connArray[0] ~=“connected”  then
                    if gemsTable[i][j] ~= false and gemsTable[i][j] ~= 0 and gemsTable[i][j] ~= nil then
                        
                        idx = idx + 1
                        makeDriftingText("+20", { x=gemsTable[i][j].x, y=gemsTable[i][j].y, t=1000, col = {255,0,0} })
                        makeDriftingBub(gemsTable[i][j].color, { x=gemsTable[i][j].x, y=gemsTable[i][j].y, t=200, del = (idx*100)  })
                        gemsTable[i][j]:removeSelf()
                        gemsTable[i][j] = 0
                        addToScore(20)
                        bubFall = bubFall + 1
                        
                    end
                end
            end
        end
    end
end

thanks for quick reply.

 

The above code is working to remove unlinked bubbles. But it checks all the bubbles so when there are more than 20 bubbles on the field. the frame rate drops :slight_smile:

 

I need some ways to limit the check or new logic to remove unlinked bubbles.

 

thank you again.

one more question. When the game shift. I need to find a way to change the index of the table and assign it to the object.

For example:

bub[i][j] = obj     – bub[1][1] = obj

I want to change it to bub[i+1][j] = obj – so it’s now bub[2][1]

 

how can I do it.

:expressionless: Sorry if it’s hard to understand because I don’t know how to explain it clearly.

[lua]

    count = count + 1
    for i=-1,1,1 do
        for j=-1,1,1 do
            
            if (i ~= 0) or (j~=0) then
                if i==0 or j==0 or (j==-1 and odd ==0) or (j==1 and odd==1) then
                    if (isNewConnection(row2+i, col2+j)) then

–if the bubbles row is 0, it means they are connected
                        if row2+i == 0  then
                            connArray2[0] = “connected”
                        else

–if not, continue to check
                                getConnections(row2+i, col2+j,connArray2)
                        end
                    end
                end
            end
        end
    end

[/lua]

 

There are a couple of things I would do.  This seems like it’s where most of the processing is happening and it’s a recursive call, so being as optimal here is a place where it’s important.

 

First table.insert() is a costly call but it seems to be happening only once per function call, but you’re iterating over the whole list, so it does get executes a fair number of times.  See this blog post:

 

http://www.coronalabs.com/blog/2013/03/12/performance-optimizations/

 

It talks about alternatives for table.insert.  See #3.  It looks like you’re just appending to the end of the table, so no need to traverse that table every time.

 

Next is those nested for loops.  You really only care about -1, -1; -1, 1; 1, -1 and 1, 1 if I read your code right.  You spend a lot of time testing to see if you’re hitting 0, which I assume is the current position.  For loops have overhead to run the loop.  There is a technique called “unrolling loops” where doing:

[lua]

array[1] = 5

array[2] = 10

array[3] = 15

[/lua]

 

is faster than

[lua]

for i = 1, 3 do

    array[i] = i * 5

end

[/lua]

 

Of course in that small example, it’s meaning less, but over hundreds and thousands of iterations, the loop mechanics impact performance.  You could replace all of that with a series of IF statements abandoning looping over the 0’s that you’re not testing.

 

If you know in side that call that you are done, you could do a return true and abort the rest of the loops running.  You might want to set a flag, if you need to stop the recursion too.

Thank you for your help.

 

I change the table.insert to another method and I’ve found a way to limit the check. The performance increases a little bit, but there is still a lag when checking unlinked bubbles.

The game is playable now but there is still a small delay.

 

I don’t get your idea about replacing all the if statements yet. Would you mind if I send you the source code and you take a look at it for me?

 

Thank you.

You are probably going to have to provide more information or some code for people to be able to respond.

– check if it is the new connection or not

local function isNewConnection(row,col)
    val2 = getValue(row,col)
 
    local test = false
    if val2 and val2 ~= false and val2 ~= 0 then
        for i=0,#connArray,1 do
            if connArray[i] == row…col then
                test = true
            end
        end
        if  test == false then
            return true
        else
            return false
        end
    end
    
    return false
end

local count = 0

 

–get connections of the bubbles, and check other bubbles
local function getConnections(row2, col2,connArray2)
    
    – insert row col vao connArray
    table.insert(connArray2, row2…col2)
    
    local odd = row2%2
    
    count = count + 1
    for i=-1,1,1 do
        for j=-1,1,1 do
            
            if (i ~= 0) or (j~=0) then
                if i==0 or j==0 or (j==-1 and odd ==0) or (j==1 and odd==1) then
                    if (isNewConnection(row2+i, col2+j)) then

–if the bubbles row is 0, it means they are connected
                        if row2+i == 0  then
                            connArray2[0] = “connected”
                        else

–if not, continue to check
                                getConnections(row2+i, col2+j,connArray2)
                        end
                    end
                end
            end
        end
    end
end

 

–remove all except connected bubbles
local function removeNotConnected()
    local idx = 0     for i = 1, #gemsTable,1 do
        for j = 0, 7,1 do
            if gemsTable[i][j] and gemsTable[i][j] ~=0 and gemsTable[i][j] ~= nil then
               
                connArray = {}
                getConnections(i,j,connArray)
                if connArray[0] ~=“connected”  then
                    if gemsTable[i][j] ~= false and gemsTable[i][j] ~= 0 and gemsTable[i][j] ~= nil then
                        
                        idx = idx + 1
                        makeDriftingText("+20", { x=gemsTable[i][j].x, y=gemsTable[i][j].y, t=1000, col = {255,0,0} })
                        makeDriftingBub(gemsTable[i][j].color, { x=gemsTable[i][j].x, y=gemsTable[i][j].y, t=200, del = (idx*100)  })
                        gemsTable[i][j]:removeSelf()
                        gemsTable[i][j] = 0
                        addToScore(20)
                        bubFall = bubFall + 1
                        
                    end
                end
            end
        end
    end
end

thanks for quick reply.

 

The above code is working to remove unlinked bubbles. But it checks all the bubbles so when there are more than 20 bubbles on the field. the frame rate drops :slight_smile:

 

I need some ways to limit the check or new logic to remove unlinked bubbles.

 

thank you again.

one more question. When the game shift. I need to find a way to change the index of the table and assign it to the object.

For example:

bub[i][j] = obj     – bub[1][1] = obj

I want to change it to bub[i+1][j] = obj – so it’s now bub[2][1]

 

how can I do it.

:expressionless: Sorry if it’s hard to understand because I don’t know how to explain it clearly.

[lua]

    count = count + 1
    for i=-1,1,1 do
        for j=-1,1,1 do
            
            if (i ~= 0) or (j~=0) then
                if i==0 or j==0 or (j==-1 and odd ==0) or (j==1 and odd==1) then
                    if (isNewConnection(row2+i, col2+j)) then

–if the bubbles row is 0, it means they are connected
                        if row2+i == 0  then
                            connArray2[0] = “connected”
                        else

–if not, continue to check
                                getConnections(row2+i, col2+j,connArray2)
                        end
                    end
                end
            end
        end
    end

[/lua]

 

There are a couple of things I would do.  This seems like it’s where most of the processing is happening and it’s a recursive call, so being as optimal here is a place where it’s important.

 

First table.insert() is a costly call but it seems to be happening only once per function call, but you’re iterating over the whole list, so it does get executes a fair number of times.  See this blog post:

 

http://www.coronalabs.com/blog/2013/03/12/performance-optimizations/

 

It talks about alternatives for table.insert.  See #3.  It looks like you’re just appending to the end of the table, so no need to traverse that table every time.

 

Next is those nested for loops.  You really only care about -1, -1; -1, 1; 1, -1 and 1, 1 if I read your code right.  You spend a lot of time testing to see if you’re hitting 0, which I assume is the current position.  For loops have overhead to run the loop.  There is a technique called “unrolling loops” where doing:

[lua]

array[1] = 5

array[2] = 10

array[3] = 15

[/lua]

 

is faster than

[lua]

for i = 1, 3 do

    array[i] = i * 5

end

[/lua]

 

Of course in that small example, it’s meaning less, but over hundreds and thousands of iterations, the loop mechanics impact performance.  You could replace all of that with a series of IF statements abandoning looping over the 0’s that you’re not testing.

 

If you know in side that call that you are done, you could do a return true and abort the rest of the loops running.  You might want to set a flag, if you need to stop the recursion too.

Thank you for your help.

 

I change the table.insert to another method and I’ve found a way to limit the check. The performance increases a little bit, but there is still a lag when checking unlinked bubbles.

The game is playable now but there is still a small delay.

 

I don’t get your idea about replacing all the if statements yet. Would you mind if I send you the source code and you take a look at it for me?

 

Thank you.