Search code examples
luacollision-detectioncoronasdk

corona + collision not working


I am learning Corona and I am trying to use the collision event. The target of the following program is that the rock is moving towards to the car using transition.to. And print a line to report the collision where it occurs.

However, it does not work. Moreover, I even cannot receive the message "enterenter", what is the reason why the program cannot even get into the enter function?

My code is as follow. Thank you in advance.

local composer = require( "composer" )
local scene = composer.newScene()


local physics = require "physics"
physics.start(); physics.pause()

local function onLocalCollision( self, event )

if ( event.phase == "began" ) then
    print( self.myName .. ": collision began with " .. event.other.myName )

elseif ( event.phase == "ended" ) then
    print( self.myName .. ": collision ended with " .. event.other.myName )
end
end


local widget = require "widget"

function scene:create( event )
print("entercreate")
local sceneGroup = self.view

local backgrd = display.newImage("background2.png",0,260)
backgrd:scale(3,3)
local car = display.newImage("car2.png",80,270)
physics.addBody(car,"static")
car.myName="Car"

local rock = display.newImage("rock.jpg",520,280)
rock:scale(0.05,0.05)
physics.addBody(rock,"static")
rock.myName="rock"


sceneGroup:insert(backgrd)
sceneGroup:insert(car)
sceneGroup:insert(rock)
transition.to(backgrd,{time=24000, x=-1800,onComplete=endScroll})
transition.to(rock,{time=4000, delay=2500,x=-40})
end

function scene:enter( event )
print("enterenter")
physics.start()
local sceneGroup = self.view
Runtime:addEventListener( "collision", onLocalCollision )
end



scene:addEventListener( "create", scene )
scene:addEventListener( "enter", scene )


return scene

Solution

  • Working code with a local and a global (Runtime) listener:

    local widget = require "widget"
    local composer = require( "composer" )
    local scene = composer.newScene()
    
    local physics = require "physics"
    physics.start()
    physics.setGravity( 0,0 )
    
    local function onGlobalCollision( event )
            local target = event.object1
            local other = event.object2
    
            if ( event.phase == "began" ) then
                print( "GLOBAL: " .. target.name .. ": collision began with " .. other.name )
            elseif ( event.phase == "ended" ) then
                print( "GLOBAL: " .. target.name .. ": collision ended  with " .. other.name )      
            end
        end
    
    local function onLocalCollision( event )
        local target = event.target
        local other = event.other
    
        if ( event.phase == "began" ) then
            print( "LOCAL: " .. other.name .. ": collision began with " .. target.name )
        elseif ( event.phase == "ended" ) then
            print( "LOCAL: " .. other.name .. ": collision ended  with " .. target.name )       
        end
    end
    
    function scene:create( event )
        print("scene:create")
    
    
        local sceneGroup = self.view
    
        local car = display.newRect( 100, 100, 100, 100 )
        car.name = "car"
        physics.addBody( car )
    
        local rock = display.newRect( 250, 250, 100, 100 )
        rock.name = "rock"
        rock:setFillColor( 0.5, 0.5, 0.5 )
        physics.addBody( rock )
        rock:addEventListener( "collision", onLocalCollision )
    
        sceneGroup:insert(car)
        sceneGroup:insert(rock)
    
        transition.to(rock,{time=4000, x = -40, y = -100})
    
        Runtime:addEventListener( "collision", onGlobalCollision )
    end
    
    function scene:enter( event )
        print("scene:enter")    
        local sceneGroup = self.view
    
    end
    
    scene:addEventListener( "create", scene )
    scene:addEventListener( "enter", scene )
    
    
    return scene
    

    The problem that you have with your code is that the two bodies are static and two static bodies can't collide with each other and that there is nothing called scene:enter in composer (so that's why it doesn't gets called and therefor not the onLocalListener).

    Some body types will — or will not — collide with other body types. In a collision between two physical objects, at least one of the objects must be dynamic, since this is the only body type which collides with any other type. See the Physics Bodies guide for details on body types.

    https://docs.coronalabs.com/daily/guide/physics/collisionDetection/index.html

    Here is some information about the Composer API and you'll that you should probably use scene:show: https://coronalabs.com/blog/2014/01/21/introducing-the-composer-api-plus-tutorial/