Colision between 2 objects.

So, I have a planet firing bullets and asteroids coming in direction of the planet. But I want do make a function that removes the bullet and the specific asteroid if the bullet hits it. Any help that you can give me?

There is the code to be more easy to you understand.

Cheers,

display.setStatusBar( display.HiddenStatusBar ) local physics = require "physics" physics.start() physics.setGravity( 0, 0 ) -- Variables local centerX = display.contentCenterX local centerY = display.contentCenterY local xmin = display.screenOriginX - 50 local xmax = display.contentWidth + 50 local ymin = display.screenOriginY - 50 local ymax = display.contentHeight + 50 local spawnIncreaseTimer local spawnNumber=0 local speedBump = 0 local earthRotation local gametimer local nSeconds = 0 local nMins = 0 local nHours = 0 local numSec = 0 local nSecs = 0 local timervalue = 0 local spawnTimer local firebullet local bg = display.newImage("images/starbg.png") bg.x = centerX bg.y = centerY local logo = display.newImage("images/Logo.png") logo.x = centerX logo.y = centerY local begin = display.newImage("images/start.png") begin.x = centerX + 50 begin.y = centerY + 45 -- Functions -- Esta função faz o texto piscar function blink() if(begin.alpha \< 1) then transition.to( begin, {time=490, alpha=1}) else transition.to( begin, {time=490, alpha=0.1}) end end txt\_blink = timer.performWithDelay(500, blink, 0) -- Esta função aumenta, de 10 em 10 segundos, o numero de asteroides que aparecem por cada 2 segundos local function spawnIncrease() spawnNumber=spawnNumber+1 spawnIncreaseTimer = timer.performWithDelay( 15000, spawnIncrease) end -- Esta função faz com que os asteroides apareçam local function spawn() for i=1,spawnNumber do local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) asteroids.class = "asteroid" if (asteroids.x \> display.screenOriginX and asteroids.x \< display.contentWidth + 1 and asteroids.y \> display.screenOriginY and asteroids.y \< display.contentHeight + 1) then display.remove(asteroids) else transition.to( asteroids, { time=math.random(3000-speedBump , 5000-speedBump), y = centerY, x = centerX , rotation = math.random(50 , 180), onComplete = colision }) speedBump = speedBump + 15 end end spawnTimer = timer.performWithDelay( 2000, spawn) end -- Esta função adiciona o score ao display local function startGame() scoreText = display.newText( "Score", 0, 0, "Helvetica", 22 ) scoreText2 = display.newText("0", 0, 0, "Helvetica", 22) scoreText.x = display.screenOriginX + 50 scoreText.y = display.screenOriginY + 20 scoreText2.x = display.screenOriginX + 50 scoreText2.y = display.screenOriginY + 45 spawnIncrease() spawn() end -- Esta função adiciona o timer ao display local function timerGame() timerTxt = display.newText("Time", 0, 0, "Helvetica", 22) timerTxt2 = display.newText("00:00:00", 0, 0, "Helvetica", 22) timerTxt.x = display.contentWidth - 15 timerTxt.y = display.screenOriginY + 20 timerTxt2.x = display.contentWidth - 15 timerTxt2.y = display.screenOriginY + 45 end -- Esta função dá inicio ao timer local function timeCount() nSeconds = timervalue if nSeconds == 0 then timerTxt2.text = "00:00:00"; else nHours = string.format("%02.f", math.floor(nSeconds/3600)); nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours\*60))); nSecs = string.format("%02.f", math.floor(nSeconds - nHours\*3600 - nMins \*60)); timerTxt2.text = nHours..":"..nMins..":"..nSecs end timervalue = timervalue + 1 gametimer = timer.performWithDelay( 1000, timeCount) end -- Esta função faz parar o aumento de asteroides que aparecem local function stopSpawnIncrease() timer.cancel( spawnIncreaseTimer ) end -- Esta função dá inicio ao jogo local function go(event) display.remove(logo) display.remove(begin) local planet = display.newImage("images/terra.png") planet.x = centerX planet.y = centerY planet:scale(4, 4) transition.to( planet, { time = 200, xScale = 1, yScale = 1, onComplete = animate} ) startGame() timerGame() timeCount() local function firebullet(event) local bullet = display.newCircle( planet.x, planet.y, 2 ) bullet.class = "bullet" physics.addBody( bullet,dynamic, { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true local deltax = event.x - planet.x local deltay = event.y - planet.y local bulletangle = math.atan2(deltay, deltax) local xforce = (math.cos(bulletangle))\*100 local yforce = (math.sin(bulletangle))\*100 bullet:applyForce( xforce, yforce, bullet.x, bullet.y ) end bg:addEventListener ( "tap", firebullet) end begin:addEventListener ( "tap", go)

Reduce that code to the minimum working code. Then work out where it’s going wrong.

First we need to make some code changes

local bullet = display.newCircle( planet.x, planet.y, 2 ) bullet.class = "bullet" physics.addBody( bullet,dynamic, { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true

To this

local bullet = display.newCircle( planet.x, planet.y, 2 ) bullet.class = "bullet" physics.addBody( bullet,"dynamic", { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true bullet.type = "bullet"

Second this:

local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) asteroids.class = "asteroid"

To this

local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) asteroids.class = "asteroid" physics.addbody(asteroids, "static") asteroids.isSensor = true

Also add this at the bottom, just to make clear the only reason I am making this global is because you are spawning actors

local function onGlobalCollision( event ) if ( event.phase == "began" ) then if (event.object1.type == "bullet" and event.object2.class == "asteroid") or (event.object2.type == "bullet" and event.object1.class == "asteroid") local myAsteroid if event.object1.type == "bullet" then myAsteroid = event.object2 else myAsteroid = event.object1 snd timer.perfromWithDelay(100, function() display.remove(myAsteroid) end end end end Runtime:addEventListener( "collision", onGlobalCollision )

Thx, the code resulted! But just one thing. When I shoot the bullet in the direction of the asteroid, the colision is being aplied when the bullet is a bit far away yet. The bullet don’t even reach the asteroid and the colision is being aplied. Do you have any idea of what can be doing that?

Cheers,

thx for the help

You might want to look at adding a radius to the astroid physics body

An easy way to see what is going is on is with this at the top of your code( but below require(“physics”)

physics.setDrawMode( “hybrid” )

Yup, the Asteroid’s radius is super huge. Thx for the tip and for the help. I am really appreciated.

I added a radius value to the asteroid, but as soon as I did that, the colision was never aplied again. Why the colision stoped working when I added the radius?

Reduce that code to the minimum working code. Then work out where it’s going wrong.

First we need to make some code changes

local bullet = display.newCircle( planet.x, planet.y, 2 ) bullet.class = "bullet" physics.addBody( bullet,dynamic, { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true

To this

local bullet = display.newCircle( planet.x, planet.y, 2 ) bullet.class = "bullet" physics.addBody( bullet,"dynamic", { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true bullet.type = "bullet"

Second this:

local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) asteroids.class = "asteroid"

To this

local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) asteroids.class = "asteroid" physics.addbody(asteroids, "static") asteroids.isSensor = true

Also add this at the bottom, just to make clear the only reason I am making this global is because you are spawning actors

local function onGlobalCollision( event ) if ( event.phase == "began" ) then if (event.object1.type == "bullet" and event.object2.class == "asteroid") or (event.object2.type == "bullet" and event.object1.class == "asteroid") local myAsteroid if event.object1.type == "bullet" then myAsteroid = event.object2 else myAsteroid = event.object1 snd timer.perfromWithDelay(100, function() display.remove(myAsteroid) end end end end Runtime:addEventListener( "collision", onGlobalCollision )

Thx, the code resulted! But just one thing. When I shoot the bullet in the direction of the asteroid, the colision is being aplied when the bullet is a bit far away yet. The bullet don’t even reach the asteroid and the colision is being aplied. Do you have any idea of what can be doing that?

Cheers,

thx for the help

You might want to look at adding a radius to the astroid physics body

An easy way to see what is going is on is with this at the top of your code( but below require(“physics”)

physics.setDrawMode( “hybrid” )

Yup, the Asteroid’s radius is super huge. Thx for the tip and for the help. I am really appreciated.

I added a radius value to the asteroid, but as soon as I did that, the colision was never aplied again. Why the colision stoped working when I added the radius?