Problem with collision detection

Hi everyone,

I’m creating my first game and I’m stuck on a problem.

Firstly, I have two objects spawning. I make these two objects move and then fall. Afterwards, two new objects spawn and so on.

And if three or more objects of the same kind (same objects) are colliding, I want them to disappear. Thus, I used the method used by corona crush with raycast. This works great when the objects are on a vertical or horizontal line. However, when the objects are like:

It does not work as only the object with two objects colliding is disappearing.

Could you please give me any advice?

Thanks in advance

Hi @peron.pierreantoine,

I think there are too many variances to understand what’s going on without seeing your code. We or the community would need to see how you’re casting the ray, where from, what conditional logic you’re using, etc. Please try to isolate only the important/relevant aspects of the code and surround it with “lua” tags for clarity:

[lua] --code [/lua]

Take care,

Brent

Hi,

Thanks for your reply.

Here’s the code I’m using to detect if three or more objects are together and then remove them:

[lua]
local destroyObject = function()

local left  = -2000
local right =  2000
local up    = -2000
local down  =  2000

for k,v in pairs( objectGrid ) do
        local totalHits = 0
        local leftHits = physics.rayCast( v.x, v.y, v.x + left, v.y, “sorted” ) or {}
        local rightHits = physics.rayCast( v.x, v.y, v.x + right, v.y, “sorted” ) or {}
        local upHits = physics.rayCast( v.x, v.y, v.x, v.y + up, “sorted” ) or {}
        local downHits = physics.rayCast( v.x, v.y, v.x, v.y + down, “sorted” ) or {}

        – Count the horizontal hits
        for i = 1, #leftHits do
            if(leftHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end
        
        for i = 1, #rightHits do
            if(rightHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end
            

        – Count the vertical hits
        for i = 1, #upHits do
            if(upHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end
        for i = 1, #downHits do
            if(leftHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end

if( totalHits > 1 ) then
        
        v.readyToDestroyObject = true    
        found1 = true
        end
        print(totalHits)
        
    end
    
    if (found1) then
    finalDestroyObject()
    end

end

finalDestroyObject = function()

for k, v in pairs (objectGrid) do

 if (v.readyToDestroyObject) then

 v:removeSelf()
 objectGrid[k] = nil
 end
 end
 end
[/lua]

This code works well if the objects are like this:

However, if they are like that…

… it does not work anymore as only the upper left blue square is disapearing. In fact, it’s the only object which hits two objects at a time and the ray cast of the two other blue squares only detects one square.

And I would like the three blue squares to disapear…

Thanks in advance

Hmm… That code should be pretty much working.  Have you tried making the rays longer?  

local left = -10000 local right = 10000 local up = -10000 local down = 10000

Also, verify that the objects have bodies by turning on hybrid draw mode:

physics.setDrawMode( "hybrid" )

The ray cast won’t work if the body is not present, offset too much, or something else that causes the ray to miss it.

PS - Please use code blocks for future posts (see the <> above your forums post when editing.)

formatyourcode.jpg

You probably also want to add some code after this to print out the contents of the ray hit lists, just to see what is going on:

local leftHits = physics.rayCast( v.x, v.y, v.x + left, v.y, "sorted" ) or {} local rightHits = physics.rayCast( v.x, v.y, v.x + right, v.y, "sorted" ) or {} local upHits = physics.rayCast( v.x, v.y, v.x, v.y + up, "sorted" ) or {} local downHits = physics.rayCast( v.x, v.y, v.x, v.y + down, "sorted" ) or {}

Thanks for your reply.

However, the problem has nothing to do with the length of the rays.

In fact, the code works well but with the second positioning I mentioned in my previous message, the ray only detetcts that one object hits two others. But the ray only detetcts that the two others hit one object each.

And I would like that all three disapear. How would you do this?

Besides, you mentioned in your last message that I should print out the contents of the ray hit lists, just to see what is going on, but how would you do this?

you login behind this is flawed.

it detects only one object, because that is reality. count those objects yourself :wink:

this will work for you

for each objects in scene:

  1. if it has 2 or more neighbors with same color, tag it for deletion +  tag all its neigbors for deletion !!! do not delete them in this step!

remove all taged objects

Hi @peron.pierreantoine,

I think there are too many variances to understand what’s going on without seeing your code. We or the community would need to see how you’re casting the ray, where from, what conditional logic you’re using, etc. Please try to isolate only the important/relevant aspects of the code and surround it with “lua” tags for clarity:

[lua] --code [/lua]

Take care,

Brent

Hi,

Thanks for your reply.

Here’s the code I’m using to detect if three or more objects are together and then remove them:

[lua]
local destroyObject = function()

local left  = -2000
local right =  2000
local up    = -2000
local down  =  2000

for k,v in pairs( objectGrid ) do
        local totalHits = 0
        local leftHits = physics.rayCast( v.x, v.y, v.x + left, v.y, “sorted” ) or {}
        local rightHits = physics.rayCast( v.x, v.y, v.x + right, v.y, “sorted” ) or {}
        local upHits = physics.rayCast( v.x, v.y, v.x, v.y + up, “sorted” ) or {}
        local downHits = physics.rayCast( v.x, v.y, v.x, v.y + down, “sorted” ) or {}

        – Count the horizontal hits
        for i = 1, #leftHits do
            if(leftHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end
        
        for i = 1, #rightHits do
            if(rightHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end
            

        – Count the vertical hits
        for i = 1, #upHits do
            if(upHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end
        for i = 1, #downHits do
            if(leftHits[i].object.myImageNumber ~= v.myImageNumber) then
                break
            end
            totalHits = totalHits + 1
        end

if( totalHits > 1 ) then
        
        v.readyToDestroyObject = true    
        found1 = true
        end
        print(totalHits)
        
    end
    
    if (found1) then
    finalDestroyObject()
    end

end

finalDestroyObject = function()

for k, v in pairs (objectGrid) do

 if (v.readyToDestroyObject) then

 v:removeSelf()
 objectGrid[k] = nil
 end
 end
 end
[/lua]

This code works well if the objects are like this:

However, if they are like that…

… it does not work anymore as only the upper left blue square is disapearing. In fact, it’s the only object which hits two objects at a time and the ray cast of the two other blue squares only detects one square.

And I would like the three blue squares to disapear…

Thanks in advance

Hmm… That code should be pretty much working.  Have you tried making the rays longer?  

local left = -10000 local right = 10000 local up = -10000 local down = 10000

Also, verify that the objects have bodies by turning on hybrid draw mode:

physics.setDrawMode( "hybrid" )

The ray cast won’t work if the body is not present, offset too much, or something else that causes the ray to miss it.

PS - Please use code blocks for future posts (see the <> above your forums post when editing.)

formatyourcode.jpg

You probably also want to add some code after this to print out the contents of the ray hit lists, just to see what is going on:

local leftHits = physics.rayCast( v.x, v.y, v.x + left, v.y, "sorted" ) or {} local rightHits = physics.rayCast( v.x, v.y, v.x + right, v.y, "sorted" ) or {} local upHits = physics.rayCast( v.x, v.y, v.x, v.y + up, "sorted" ) or {} local downHits = physics.rayCast( v.x, v.y, v.x, v.y + down, "sorted" ) or {}

Thanks for your reply.

However, the problem has nothing to do with the length of the rays.

In fact, the code works well but with the second positioning I mentioned in my previous message, the ray only detetcts that one object hits two others. But the ray only detetcts that the two others hit one object each.

And I would like that all three disapear. How would you do this?

Besides, you mentioned in your last message that I should print out the contents of the ray hit lists, just to see what is going on, but how would you do this?

you login behind this is flawed.

it detects only one object, because that is reality. count those objects yourself :wink:

this will work for you

for each objects in scene:

  1. if it has 2 or more neighbors with same color, tag it for deletion +  tag all its neigbors for deletion !!! do not delete them in this step!

remove all taged objects