Collisions

So a friend and i are developing a game where there are laser beams, zombies, and a happy face. With one collision we want the happy to disappear when colliding with the zombie (which we accomplished) and where the zombie disappears when colliding with the laser beam. We’ve spent about a month working on this and no luck. Here is all the code.

display.setStatusBar(display.HiddenStatusBar)

local physics = require “physics”

physics.start()

physics.setGravity(0,0)

local pWidth, pHeight = display.actualContentWidth, display.actualContentHeight

– create wall objects

local topWall = display.newRect( 0, 0, display.contentWidth+20, 20 )

local bottomWall = display.newRect( 0, display.contentHeight - 10, display.contentWidth, 20 )

local leftWall = display.newRect( 0, 0, 10, display.contentHeight )

local rightWall = display.newRect( display.contentWidth - 10, 0, 10, display.contentHeight+20 )

– make them physics bodies

physics.addBody(topWall, “static”, {density = 1.0, friction = 1, bounce = 40, isSensor = false})

physics.addBody(bottomWall, “static”, {density = 1.0, friction = 1, bounce = 40, isSensor = false})

physics.addBody(leftWall, “static”, {density = 1.0, friction = 1, bounce = 40, isSensor = false})

physics.addBody(rightWall, “static”, {density = 1.0, friction = 1, bounce = 40, isSensor = false})

local background = display.newImage(“background.jpg”)

local happy = display.newImage(“happy.png”)

happy.x = 100

happy.y = 100

physics.addBody(happy, “dynamic”)

– TOUCH EVENTS FOR HAPPY MOVEMENT

function touchScreen(event)

        if event.phase == “ended” then

                transition.to(happy,{time=700, x=event.x, y=event.y})

        end

end

Runtime:addEventListener(“touch”, touchScreen)

– ok shlok, trying to make collisions work anything after this if it doesn’t work u can delete

 local backgroundmusic = audio.loadStream("_ElecTechno.m4a")

local backgroundmusic2 = audio.play( backgroundmusic, { loops=-1, fadein=2000 } )

– every x seconds

local function listener(me)

    transition.to (me, {time = math.random(1000,4000), x = math.random(10,310), y = -30, onComplete = function()listener(me)end});

end

–Spawning multiple objects in randoms locations

local function spawnzombie()

    local zombie = display.newImageRect(“zombie.jpg”, 45, 45);

    zombie.x = 200;

    zombie.y = 200;

    function movezombie()

    transition.to(zombie,{time=7000, x=math.random(0,500), y=math.random(0,600), onComplete=movezombie});

end

    physics.addBody(zombie, “dynamic”, {density = 0.1, bounce = 0.1, friction = .1, radius = 0});

    movezombie()

    --Adding touch event

    zombie:addEventListener(“touch”, zombie);

    zombie.collType = “dynamic”

physics.addBody( zombie, { bounce=10.0, friction=1.0 } )

function onCollision(event)

–print(“collide!”)

happy:removeSelf()

end

Runtime:addEventListener(“collision”, onCollision)

end

local total_zombie = 100

tmr = timer.performWithDelay(2000, spawnzombie, total_zombie);

– BUTTON code

local widget = require( “widget” )

local function handleButtonEvent( event )

        local phase = event.phase

        if “ended” == phase then

                print( “you pressed and released a button!” )

        end

end

– guns

local function fireLasers()

  local laserbeam = display.newImage(“laserbeam.jpg”)

  laserbeam:scale( 0.5, 0.5 )

  laserbeam.x = happy.x

  laserbeam.y = happy.y

  physics.addBody(happy, “dynamic”)

  transition.to(laserbeam, {time=1000, x = math.random() ,y = math.random(), onComplete=movelaserbeam});

end

local fireButton = display.newImage( “firebutton.jpg” )

fireButton.x = 50

fireButton.y = display.contentHeight-50

local function handleFireButton( event )

        if ( event.phase == “began” ) then

                fireLasers()

        elseif ( event.phase == “ended” ) then

                fireLasers()

        end

        return true

end

fireButton:addEventListener( “touch”, handleFireButton )

local needToFire = false

local function handleEnterFrame( event)

        if ( needToFire == true ) then

                fireLasers()

        end

end

Runtime:addEventListener( “enterFrame”, handleEnterFrame )

local fireButton = display.newImage( “firebutton.jpg” )

fireButton.x = 50

fireButton.y = display.contentHeight-50

local function handleFireButton( event )

                if ( event.phase == “began” ) then

                        needToFire = true

                elseif ( event.phase == “ended” and needToFire == true ) then

                needToFire = false

        end

        return true

end

fireButton:addEventListener( “touch”, handleFireButton )

– ugh

local needToFire = false

local function handleEnterFrame( event )

   if ( needToFire == true ) then

      fireLasers()

   end

end

Runtime:addEventListener( “enterFrame”, handleEnterFrame )

local function handleFireButton2( event )

   if ( event.phase == “began” ) then

      – fire the weapon

      needToFire = true

   elseif ( event.phase == “ended” and needToFire == true ) then

      – stop firing the weapon

      needToFire = false

   end

   return true

end

local fireButton2 = widget.newButton{

   width = 64,

   height = 64,

   defaultFile = “firebutton.jpg”,

   overFile = “button1.jpg”,

   onEvent = handleFireButton

}

fireButton.x = 50

— splash screen?

local splashscreen = display.newImage( “ins.png” );

local removesplashbutton  --up-value reference

local function removeSplash( event )

   splashscreen:removeSelf()

   removesplashbutton:removeSelf()

end

removesplashbutton = widget.newButton{

        width = 100,

        height = 100,

        defaultFile = “smallbutton.png”,

        overFile = “button1.jpg”,

        onPress = removeSplash,

}

local function exit1( event )

os.exit()

end

exitbutton = widget.newButton{

width = 10,

height = 10,

defaultFile = “exitbutton1.jpg”,

overFile = “button1.jpg”,

onPress = exit1,

}

function onCollision(event)

–print(“collide!”)

zombie:removeSelf()

end

The first thing I would is to give an ID to each object, which we can more easily use to identify the collisions.
So for example:

 

laster.id = "laser"; zombie.id = "zombie"; happy.id = "happy";

After that, I would have only one collision listener, not Runtime, but attached to the zombies.
 

function zombie:collision(event) if event.phase == "began" then if event.other.id == "happy" then --this will trigger only if a zombie collides with an happy face if not event.other.wasHit then --this makes sure we call the timer to remove the happy face only once for each happy face event.other.wasHit = true; timer.performWithDelay(100, event.other.removeSelf, 1); end elseif event.other.id == "laser" then --this will trigger only if a zombie collides with a laser if not self.wasHit then --this makes sure we call the timer to remove this zombie only once self.wasHit = true; timer.performWithDelay(100, self.removeSelf, 1); end end end end zombie:addEventListener("collision", zombie);

I’m not a big fan of the use of timers during gameplay (I would suggest an enterFrame event for each object that checks wether a specific parameter is true or not. If it’s true, the object gets removed), but for simplicity and since it’s needed because you can’t remove objects during a collision, they’re there.
 

Make sure to read this guide (perhaps a few times to make sure you understand it).  Also pay attention to the section on Collision Filters which is a good way to make sure only certain things collide with others:

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html

Rob

i tried to implement that code, but it just got rid of the buttons and no zombies appeared and it was just happy. Help please

I’ll try to help you based on the code you posted in the initial post (:

The spawnzombie function must be like this:

local function spawnzombie() local zombie = display.newImageRect("zombie.jpg", 45, 45); zombie.x = 200; zombie.y = 200; function movezombie() transition.to(zombie,{time=7000, x=math.random(0,500), y=math.random(0,600), onComplete=movezombie}); end physics.addBody(zombie, "dynamic", {density = 0.1, bounce = 0.1, friction = .1, radius = 0}); movezombie() --Adding touch event zombie:addEventListener("touch", zombie); zombie.collType = "dynamic" physics.addBody( zombie, { bounce=10.0, friction=1.0 } ) function zombie:collision(event) if event.phase == "began" then if event.other.id == "happy" then if not event.other.wasHit then event.other.wasHit = true; timer.performWithDelay(100, event.other.removeSelf, 1); end elseif event.other.id == "laser" then if not self.wasHit then self.wasHit = true; timer.performWithDelay(100, self.removeSelf, 1); end end end end zombie:addEventListener("collision", zombie); end 

this bit:

local happy = display.newImage("happy.png") happy.x = 100 happy.y = 100 physics.addBody(happy, "dynamic")

changes to:

local happy = display.newImage("happy.png") happy.x = 100 happy.y = 100 happy.id = "happy"; physics.addBody(happy, "dynamic")

And this other one:

local function fireLasers() local laserbeam = display.newImage("laserbeam.jpg") laserbeam:scale( 0.5, 0.5 ) laserbeam.x = happy.x laserbeam.y = happy.y physics.addBody(happy, "dynamic") transition.to(laserbeam, {time=1000, x = math.random() ,y = math.random(), onComplete=movelaserbeam}); end 

to this:

local function fireLasers() local laserbeam = display.newImage("laserbeam.jpg") laserbeam:scale( 0.5, 0.5 ) laserbeam.x = happy.x laserbeam.y = happy.y laserbeam.id = "laser"; physics.addBody(happy, "dynamic") transition.to(laserbeam, {time=1000, x = math.random() ,y = math.random(), onComplete=movelaserbeam}); end

It shouldn’t break anything. Also make sure to use the terminal to check for any error Corona might throw out.

The first thing I would is to give an ID to each object, which we can more easily use to identify the collisions.
So for example:

 

laster.id = "laser"; zombie.id = "zombie"; happy.id = "happy";

After that, I would have only one collision listener, not Runtime, but attached to the zombies.
 

function zombie:collision(event) if event.phase == "began" then if event.other.id == "happy" then --this will trigger only if a zombie collides with an happy face if not event.other.wasHit then --this makes sure we call the timer to remove the happy face only once for each happy face event.other.wasHit = true; timer.performWithDelay(100, event.other.removeSelf, 1); end elseif event.other.id == "laser" then --this will trigger only if a zombie collides with a laser if not self.wasHit then --this makes sure we call the timer to remove this zombie only once self.wasHit = true; timer.performWithDelay(100, self.removeSelf, 1); end end end end zombie:addEventListener("collision", zombie);

I’m not a big fan of the use of timers during gameplay (I would suggest an enterFrame event for each object that checks wether a specific parameter is true or not. If it’s true, the object gets removed), but for simplicity and since it’s needed because you can’t remove objects during a collision, they’re there.
 

Make sure to read this guide (perhaps a few times to make sure you understand it).  Also pay attention to the section on Collision Filters which is a good way to make sure only certain things collide with others:

http://docs.coronalabs.com/guide/physics/collisionDetection/index.html

Rob

i tried to implement that code, but it just got rid of the buttons and no zombies appeared and it was just happy. Help please

I’ll try to help you based on the code you posted in the initial post (:

The spawnzombie function must be like this:

local function spawnzombie() local zombie = display.newImageRect("zombie.jpg", 45, 45); zombie.x = 200; zombie.y = 200; function movezombie() transition.to(zombie,{time=7000, x=math.random(0,500), y=math.random(0,600), onComplete=movezombie}); end physics.addBody(zombie, "dynamic", {density = 0.1, bounce = 0.1, friction = .1, radius = 0}); movezombie() --Adding touch event zombie:addEventListener("touch", zombie); zombie.collType = "dynamic" physics.addBody( zombie, { bounce=10.0, friction=1.0 } ) function zombie:collision(event) if event.phase == "began" then if event.other.id == "happy" then if not event.other.wasHit then event.other.wasHit = true; timer.performWithDelay(100, event.other.removeSelf, 1); end elseif event.other.id == "laser" then if not self.wasHit then self.wasHit = true; timer.performWithDelay(100, self.removeSelf, 1); end end end end zombie:addEventListener("collision", zombie); end 

this bit:

local happy = display.newImage("happy.png") happy.x = 100 happy.y = 100 physics.addBody(happy, "dynamic")

changes to:

local happy = display.newImage("happy.png") happy.x = 100 happy.y = 100 happy.id = "happy"; physics.addBody(happy, "dynamic")

And this other one:

local function fireLasers() local laserbeam = display.newImage("laserbeam.jpg") laserbeam:scale( 0.5, 0.5 ) laserbeam.x = happy.x laserbeam.y = happy.y physics.addBody(happy, "dynamic") transition.to(laserbeam, {time=1000, x = math.random() ,y = math.random(), onComplete=movelaserbeam}); end 

to this:

local function fireLasers() local laserbeam = display.newImage("laserbeam.jpg") laserbeam:scale( 0.5, 0.5 ) laserbeam.x = happy.x laserbeam.y = happy.y laserbeam.id = "laser"; physics.addBody(happy, "dynamic") transition.to(laserbeam, {time=1000, x = math.random() ,y = math.random(), onComplete=movelaserbeam}); end

It shouldn’t break anything. Also make sure to use the terminal to check for any error Corona might throw out.