Collision happens outside the display, not on enemies

Hi!
This is driving me crazy. I have a turret which shoots bullets. I have planes coming across the screen. The bullets is supposed to shoot down the planes, but no collision appears when they hit - they just flies by. Instead, the collision happens when I shoot on the walls of the display!

local function onCollision(self, event)  
 -- Bullet hit enemy  
 print("collision")  
  
 if (self.name == "bullet" and event.other.name == "plane") then  
 local explosion = display.newImage( "poof.png", bullet.x, bullet.y )   
 bullet:removeSelf()  
 plane:removeSelf()  
 local function removeExplosion( event )   
 explosion:removeSelf()   
 end  
  
 timer.performWithDelay( 50, removeExplosion)   
  
 end  
end  
  
local fire = function()  
  
 print("fire")  
 local bullet = display.newImage("bullet.png")  
  
 bullet.x = weapon.x  
 bullet.y = weapon.y  
  
 physics.addBody(bullet, "kinematic", {bounce = 0})  
 bullet.name = "bullet"  
  
 bullet.velocity = {}  
  
 bullet.velocity.x = -math.cos( math.rad( weapon.rotation - 90 ) )  
 bullet.velocity.y = -math.sin( math.rad( weapon.rotation - 90 ) )  
  
 bullets[#bullets + 1] = bullet  
  
 bullet.collision = onCollision  
 bullet:addEventListener("collision", bullet)  
  
 gameLayer:insert(bullet)  
end  
  
local function gameLoop(event)   
 if event.time - timeLastPlane \>= math.random(4000, 5000) then  
 require "sprite"  
  
 local sheet  
  
 sheet = sprite.newSpriteSheet( "plane.png", 225, 125 )  
 planexscale = 0.3  
 planeyscale = 0.3  
 thetime = 10000  
 pentagonShape = { -3.68085098266602, -13.5531921386719 , 28.3404273986816, -14.0851058959961 , 29.8297882080078, 3.04255294799805 , -11.1276588439941, 14.2127661705017 , -27.6170210838318, 11.021276473999 , -30.8085105419159, -10.7872333526611 }  
  
 stringHeight = math.random(20, 190)  
  
 local spriteSet = sprite.newSpriteSet(sheet, 1, 4)  
 sprite.add( spriteSet, "plane", 1, 4, 200, 0 )   
  
 local instance = sprite.newSprite( spriteSet )  
 instance.x = 520  
 instance.y = stringHeight  
 instance.xScale = planexscale  
 instance.yScale = planeyscale  
  
 instance:prepare("plane")  
 instance:play()  
  
 instance.name = "plane"  
  
 physics.addBody(instance, "kinematic", {bounce = 0, shape=pentagonShape})  
  
 transition.to( instance, { time=thetime, alpha=1, x=-420, y=stringHeight, onComplete = function(self) self.parent:remove(self); self = nil; end } )  
 enemiesLayer:insert(instance)  
 timeLastPlane = event.time  
  
 end  
end  
  
local onUpdate = function( event )  
  
 for i = 1, #bullets, 1 do  
 bullets[i]:move( bullets[i].velocity.x \* bulletSpeed, bullets[i].velocity.y \* bulletSpeed )  
 end  
  
end  
  
local onTouch = function( event )  
  
 if event.phase == "began" or event.phase == "moved" then  
 local angle = math.angleBetween( event, weapon )  
  
 weapon.rotation = angle   
  
 if (weapon.rotation \> 0) and (weapon.rotation \< 180) then  
 weapon.xScale = 1  
 elseif (weapon.rotation \> 180) and (weapon.rotation \< 359) then  
 weapon.xScale = -1  
 end  
  
 else  
 fire()  
 end  
  
end  
Runtime:addEventListener("enterFrame", gameLoop)  
Runtime:addEventListener( "enterFrame", onUpdate )  
Runtime:addEventListener( "touch", onTouch )  
  

Any idea what I’m doing wrong?

Best regards,
joelwe [import]uid: 54640 topic_id: 9885 reply_id: 309885[/import]

If the bullets move too fast, you may not get a hit registration. Try setting isBullet to true to enable continuous collision detection. [import]uid: 51516 topic_id: 9885 reply_id: 36054[/import]

Thanks for your reply Seth, but this doesn’t change anything.

I tried to put

bullet.isBullet = true  
local state = bullet.isBullet  

in fire function, but the problem still occur; I don’t get any hit count when I shoot on the planes, but I get hit counts when I shoot on the walls of the display! [import]uid: 54640 topic_id: 9885 reply_id: 36061[/import]

*bump*

I’m sorry that I’m a pain in the ass, but this function is essential for my game!

I get a collision when I set the physics of the bullet to “dynamic”, but not when it’s on “kinematic”. Can it be the layers that’s messing with me?

Best regards,
joelwe

[import]uid: 54640 topic_id: 9885 reply_id: 36225[/import]

kinematic object don’t collide with any other object.

Here is an excerpt from the docs.

  • static bodies don’t move, and don’t interact with each other; examples of static objects would include the ground, or the walls of a pinball machine.
  • dynamic bodies are affected by gravity and collisions with the other body types.
  • kinematic objects are affected by forces but not by gravity, so you should generally set draggable objects to “kinematic”, at least for the duration of the drag event.

The default body type is “dynamic”. [import]uid: 48521 topic_id: 9885 reply_id: 36227[/import]

Oh, that explains it! :stuck_out_tongue:

Do you know any example that does what I’m looking for? Or how I can change the above code so that it works with dynamic? I’ve seen the bullet sample, but I can’t figure out how I should implement it with the above code. I know that it’s much to ask for, but it would be very appreciated!

Bullet sample:

local bricks = {}  
local n = 0  
   
local function throwBrick()  
 n = n + 1  
 bricks[n] = display.newImage( "brick.png", -20, 140 - (n\*20) )  
 physics.addBody( bricks[n], { density=3.0, friction=0.5, bounce=0.05 } )  
   
 -- remove the "isBullet" setting below to see the brick pass through cans without colliding!  
 bricks[n].isBullet = true  
   
 bricks[n].angularVelocity = 100  
 bricks[n]:applyForce( 1200, 0, bricks[n].x, bricks[n].y )  
end  
   
local function start()  
 -- throw 3 bricks  
 timer.performWithDelay( 360, throwBrick, 3 )  
end  
   
-- wait 800 milliseconds, then call start function above  
timer.performWithDelay( 800, start )  

Best regards,
joelwe [import]uid: 54640 topic_id: 9885 reply_id: 36233[/import]

First off, your planes can’t be kinematic either. Did you check that?

If you have IRC, please drop by at IRC channel #corona on irc.freenode.net where we can chat live to help you :slight_smile:

[import]uid: 48521 topic_id: 9885 reply_id: 36235[/import]

Finally got it to work thanks to the guys on irc!

local fire = function()  
   
 print("fire")  
 local bullet = display.newImage("bullet.png")  
  
 bullet.x = weapon.x  
 bullet.y = weapon.y  
  
 -- Set bullet to dynamic  
 physics.addBody(bullet)  
  
 -- Set bullet to isBullet  
 bullet.isBullet = true  
 bullet.name = "bullet"  
  
 bullet.velocity = {}  
  
 -- Set the velocity \* 50  
 bullet.velocity.x = -math.cos( math.rad( weapon.rotation - 90 ) ) **\*50**  
 bullet.velocity.y = -math.sin( math.rad( weapon.rotation - 90 ) ) **\*50**  
  
 bullets[#bullets + 1] = bullet  
  
 bullet.collision = onCollision  
 bullet:addEventListener("collision", bullet)  
  
 gameLayer:insert(bullet)  
end  

Thanks a million! [import]uid: 54640 topic_id: 9885 reply_id: 36242[/import]