Search code examples
luacoronasdkcollision-detectionlua-table

Collision Detection with lua using Corona


I'm having an issue with detecting all the objects in a table for a specific collision. I can only get the score to increase when the first object in the table is hit with snowball. Here's the code I'm using for the object's creation and collision. I have a function call for createSnowBall() after button push. That part works fine.

local physics = require("physics")
physics.start()
physics.setGravity( 0, 0 )

local snowBalls = {}
local ornaments = {}
local score = 0

local scoreText = display.newText( "Score: " .. score, 70, 25, native.systemBoldFont, 32 )

function createSnowBall()
    snowBall = display.newImageRect( "snowball.png", 20, 20)
    snowBall.x = gun.x
    snowBall.y = HEIGHT - 110
    physics.addBody( snowBall, { density = 1.0, friction = 1, bounce = 0, radius = 20 } )
    snowBall.isSnowBall = true
    snowBalls[#snowBalls+1] = snowBall
    moveSnowBall(snowBall)
    return snowBall
end

function createOrnament(num)
        if num == 1 then
            ornament = display.newImageRect( "blueO.png", 30, 40)
        elseif num == 2 then
            ornament = display.newImageRect( "redO.png", 30, 40)
        elseif num == 3 then
            ornament = display.newImageRect( "greenO.png", 30, 40)
        end
    ornament.isOrnament = true
    ornaments[#ornaments+1] = ornament
    ornament.x = math.random(50, 270)
    ornament.y = 3
    local radius = 15
    physics.addBody( ornament, { density = 1.0, friction = 1, bounce = 1, radius = radius } )
    ornament:applyForce(35, 70, ornament.x + 4, ornament.y + 4)
    return ornament
end
createOrnament(math.random(1, 3))

function snowBallCollision(event)
    if event.phase == "began" then
        local target = event.other 
            if target.isSnowBall then
                score = score + 5
                scoreText.text = "Score: " .. score
            end
    end
end

ornament:addEventListener( "collision", snowBallCollision )

Solution

  • This issue occurs due to the line:

    ornament:addEventListener( "collision", snowBallCollision )
    

    Here you are only adding listener to the objects only once, and that will get assigned to the objects which are previously generated and not yet destroyed.

    So, just delete that line from your code, and whenever you are calling the line:

    createOrnament(math.random(1, 3))
    

    Replace it with:

    local myOrnament = createOrnament(math.random(1, 3)) -- Since 'createOrnament' returns the object
    myOrnament:addEventListener( "collision", snowBallCollision ) -- assign listener to the newly created object
    

    This will assign the listener to all your 'myOrnament' objects.

    Keep Coding............. :)