Collision not Working! Please help Bullet - Enemy!

Hello everybody! I am using a spritesheet to display an enemy character and an image to represent a bullet. the code I am using for collision detection is not working AT ALL and i was wondering what was wrong, it detects the enemy touching the floor but not the bullet they are both dynamic.

local function onCollision(self, event) if self.name == "bullet" and event.other.name == "soldier" then print("collision!") end end

I am just having it print a message if they touch but it never detects! Please Help!

Did you tried it with:

local function onGlobalCollision( event ) ?

Hi @krpatel420,

Is this “bullet” exactly as you state? A small object moving very fast? If so, you might need to increase the collision sensitivity on it with the “.isBullet” property (which increases how often the object detects collision, at a tiny but necessary performance penalty, but not enough to notice if you’re using it sparingly).

Regards,

Brent

Just did still did not detect I wonder why.

Here is the code for the bullet.

function spawnBullet() bullet = display.newImage("bullet.png") bullet.x = 480 bullet.y = 270 bullet.name = 'bullet' bullet.isBullet = true bullet.isSensor = true physics.addBody(bullet, "dynamic", {bounce = 0}) --bullets.insert(bullets, bullet) bullet:applyLinearImpulse( -1/2, 0, bullet.x, bullet.y ) end

Hi @krpatel420,

I see you’re setting both “.isBullet” and “.isSensor” before you create the actual physics body. All physical properties must be declared after you create the body.

Brent

do i have to have it outside the function? this is my new code - sorry if i’m frustrating i’m new to this!

function spawnBullet() bullet = display.newImage("bullet.png") bullet.x = 480 bullet.y = 270 bullet.name = 'bullet' physics.addBody(bullet, "dynamic", {bounce = 0}) bullet.isBullet = true bullet:applyLinearImpulse( -1/2, 0, bullet.x, bullet.y ) end

Inside the function is correct, just after the declaration of the physics body.

Brent

Yea so that is where it is at now, i am convinced something is going wrong with collision detection. Here is the relevant soldier code - the rest is just running the sprite.

soldier = display.newSprite( enemy, sequenceData ) soldier.x = -30 soldier.y = 270 soldier:play() physics.addBody(soldier, "static") soldierhealth = 10

Did you follow the full collisions guide here?

http://developer.coronalabs.com/content/game-edition-collision-detection

It’s possible you forgot to declare the correct collisions listener? I assume you didn’t tinker with collision filters yet, did you? That could also be preventing the collision, but you probably haven’t done that yet…

still experimenting… and still not working. Any other suggestions or sample code?

This code detects the collision how do i make it so it only does something when the bullet hits it event.other.type == bullet???

local function onLocalCollision(e) print("COLLISON") end soldier:addEventListener( "collision", onLocalCollision )

Hi @krpatel420,

It appears that you’re mixing up the “local” vs. “global” collision styles. If you want to use the local method, the proper format is this:

[lua]

local function onLocalCollision( self, event )

  --solider is “self”

  --other object is “event.other”

end

soldier.collision = onLocalCollision

soldier:addEventListener( “collision”, soldier )

[/lua]

Notice, especially, how you need to add the “.collision” property to the solider, which points to the collision handling function. The name of the function does not go inside the “addEventListener” line in the case of a local collision listener.

Brent

local function onLocalCollision( self, event ) if event.other.name == "bullet" then soldierHealth = soldierHealth - 5 if soldierHealth == 0 then print("Dead!") end end end soldier.collision = onLocalCollision soldier:addEventListener( "collision", soldier )

This seems to work to detect the collision now i can’t seem to get the health to work correctly when do i put in the variable soldierHealth = 10. Right now it is in the spawnSoldier() function  and in the game.lua but neither seem to be the right place. Thanks for your help so far I was getting extremely frustrated!

EDIT: Ohh I see because the function is local so now i have to make it global so the values are shared correct?

EDIT2: Now that i have changed the code the listener is thinking the bullet collided with the bullet even though i haven’t event fired it yet… I wonder why. Also when i make it display the e.target.name it says nil, but the bullet works correctly.

Thank you! It’s working correctly now! All i have to do is get the soldier to dissapear once his health == 0, for some reason he stays though. i am using display.remove(e.target) also tried display.remove(soldier)

EDIT: It works with the bullet, not the soldier, is it because it is a sprite sheet being spawned in or that there are multiple of them?

Hi @krpatel420,

What is your “common” physics object? Is there one soldier and many bullets? Or one bullet shooting down many soldiers? In general, you should try to put collision listeners on the least amount of objects.

For example, if you have one bullet and 50 soldiers, you should put the collision listener on the bullet and the soldiers (or anything the bullet hits) becomes the “event.other” object in the collision. In contrast, if you have 1 soldier and 50 bullets, the collision listener should be placed on the soldier, and then the bullets become the “event.other” in the collision while the soldier remains the “self” object.

If you have both many bullets AND many soldiers, you might want to consider a “global” collision listener instead.

Again, remember, to remove (or just reference) the objects in a local-style collision, “self” is the object that has the listener applied, and “event.other” is an object which it collides with.

Brent

They are both being spawned in in total you have 21 bullets(unless you upgrade) and 1 +3(wave #) soldiers and other unplanned “enemies” coming on different waves. It is now detecting the collisions but i can’t get the sprite/soldier to get off the screen, the bullet does though. i am using display.remove(e.target) also tried display.remove(soldier). for the bullet display.remove(bullet) works perfectly

In the collision handler, as I mentioned, the objects involved are “self” and “event.other” (at least for a local-style collision… it’s different for a global-style Runtime collision listener, as shown in the documentation).

So, to remove the soldier in the example, it’s:

[lua]

display.remove( self ) ; self = nil

[/lua]

BUT, this doesn’t entirely clear the object from memory. You need to “nil” its reference if you have the solider referenced somewhere outside the scope of the spawn function. If you don’t, Lua will not consider this object “garbage” and it will remain in memory, causing a memory leak.

Brent

The above code still hasn’t worked… it does print DEAD but nothing happens the the actual soldier on the simulator.

function onCollision(e) if e.phase == "began" then if(e.other.name == "bullet") then display.remove(e.other) soldierHealth = soldierHealth - 5 print(soldierHealth) if soldierHealth == 0 then display.remove( self ) ; self = nil print("DEAD") end end end end

Now it looks like you’ve switched to the “global-style” collision listener. That’s OK, but “self” is not a parameter in that usage. Instead, it’s “event.object1” and “event.object2”.

Review the documentation carefully on this:

http://developer.coronalabs.com/content/game-edition-collision-detection

If I may ask, is this your first game in Corona? You might find some game tutorials very useful. There are two video tutorials on YouTube that I can think of:

youtube.com/watch?v=Mw-TWx3CH84

youtube.com/watch?v=0GtUxdSeWzk

Hope this helps,

Brent

It actually isn’t this is my second but my first was so uber simple it wasn’t even funny, it had 4 screens, and the gameplay was running away from two “enemies” using transition.to. Sorry if i seem like a noob at this I’m just 14 trying to make some apps it is really fun, but i don’t think i really get the Collision parts of it correctly, the rest i understand!