Help me with a bullet collision problem ! pls

Hi guys, I’ve a problem with my code to rilieve collision between a bullet and an enemy.
With this code , the bullets appears and moves correctly, but they don’t rilieve any collision.
Can you help me pls?  :wacko:  :wacko:

This code is the bullet function.

-- Heart bar module local physics=require("physics") local blob=require("scene.game.lib.blob") -- Define module local M = {} function M.new( options ) local projectile = display.newImageRect( "scene/game/img/seme.png", w, h ) local direction function projectile:fireLeft() projectile = display.newImageRect( "scene/game/img/seme.png", w, h ) projectile.alpha = 1 projectile.x=self.x-100 projectile.y=self.y projectile.isBullet=true physics.addBody( projectile, "dynamic", {isSensor=true, bounce=0, density=2} ) projectile.gravityScale = 0 direction=self.flip print(direction) projectile:setLinearVelocity( -800, 0 ) timer.performWithDelay(2000, function() display.remove(projectile) end) end function projectile:fireRight() projectile = display.newImageRect( "scene/game/img/seme.png", w, h ) projectile.alpha = 1 projectile.x=self.x projectile.y=self.y projectile.isBullet=true physics.addBody( projectile, "dynamic", { isSensor=true, bounce=0, density=2} ) projectile.gravityScale = 0 direction=self.flip print(direction) projectile:setLinearVelocity( 800, 0 ) timer.performWithDelay(2000, function() display.remove(projectile) end) end function projectile:collision( event ) print("sssssssss") local phase = event.phase local other = event.other -- local y1, y2 = self.y + 50, other.y - ( other.type == "enemy" and 25 or other.height/2 ) -- local vx, vy = self:getLinearVelocity() if phase == "began" then print("sjsjjsjsjsjsjs") if self and ( other.type == "blob" or other.type == "enemy" ) then print("aaaaa") other:die() end end end local function onLocalCollision( self, event ) if ( event.phase == "began" ) then if self and ( other.type == "blob" or other.type == "enemy" ) then print("aaaaa") other:die() end end end function projectile:finalize() -- On remove, cleanup instance display.remove( projectile ) end projectile:addEventListener( "finalize" ) projectile.collision = onLocalCollision projectile:addEventListener( "collision") -- Return instance projectile.name="bullet" projectile.type="bullet" return projectile end return M

and this a function inside the Hero file  that implements the joystick and recall the bullet function when the user push c button or a display button.

local function key( event ) local phase = event.phase local name = event.keyName if ( phase == lastEvent.phase ) and ( name == lastEvent.keyName ) then return false end -- Filter repeating keys if phase == "down" then if "left" == name or "a" == name then left = -acceleration flip = -0.133 end if "right" == name or "d" == name then right = acceleration flip = 0.133 elseif "space" == name or "buttonA" == name or "button1" == name or "c" == name or "buttonB" == name or "button2" == name then if ("space" == name or "buttonA" == name or "button1" == name) then instance:jump() end if ("c" == name or "buttonB" == name or "button2" == name) then print("fire") print(flip) instance:fireLaser() end end if not ( left == 0 and right == 0 ) and not instance.jumping then instance:setSequence( "walk" ) instance:play() end elseif phase == "up" then if "left" == name or "a" == name then left = 0 end if "right" == name or "d" == name then right = 0 end if left == 0 and right == 0 and not instance.jumping then instance:setSequence("idle") end end lastEvent = event end function instance:fireLaser() if flip == 0.133 then self.bullet:fireRight() elseif flip == -0.133 then self.bullet:fireLeft() end end

pls help me!!! this is the last thing and i finish…I can’t find the solution  :unsure:

Thank you!

In cases like this, it is best to create a small project that demonstrates your issue. The biggest issue here is that while we know how you are firing the bullet, we don’t know what you are firing the bullet at, i.e. we can’t know anything for certain about why your collisions aren’t working because we only have one of the two pieces that are supposed to collide.

There are also some issues in your function with how you create the projectile and how you could make your code easier. For instance, you are creating the display image twice, but you shouldn’t do that. Secondly, you don’t need to write the almost exact same function twice in a row. Just use one function and enter different values for some of the arguments/parameters.

Now, about your collision issue, one possible reason could be that you set “.isBullet” before the object actually has a physics body. I’m not sure if the order matters, but I would lean towards yes. Secondly, you fire the bullets at a crazy speed. Even if the projectile is a bullet, I’m not sure if it can detect a collision of your tiny projectile is travelling hundreds of pixels per second and it is supposed to hit a fairly small enemy.

Typically, in games, if you want to create guns that fire bullets at instant or near instant speed, you’d use a hit scan technique where you simply calculate if the bullet would hit at the time the gun was fired instead of actually shooting a projectile and seeing if it hits later.

ok, thanks…but what do you mean with small project? 
 

yes, but  if i create the display image once, corona report me an error with nil value on the projectile inside the functions…I know that the problem is there but I don’t know how resolve…

Thanks

Well, here’s just a small snipped and an example on how you could make the function a bit shorter.

function projectile:fire( leftOrRight ) --projectile.alpha = 1 -- objects have alpha value of 1 by default, so this probably does nothing? --projectile.x=self.x -- this line seems to just set the object's x position to itself, i.e. does nothing. --projectile.y=self.y -- same as above physics.addBody( projectile, "dynamic", {isSensor=true, isBullet=true, bounce=0, density=2} ) projectile.gravityScale = 0 direction = self.flip if leftOrRight and leftOrRight == "left" then projectile.x = projectile.x - 100 projectile:setLinearVelocity( -800, 0 ) else projectile:setLinearVelocity( 800, 0 ) end timer.performWithDelay(2000, function() display.remove(projectile) end) end

Since your fireLeft() and fireRight() methods only differences are the projectile’s initial x position and which way you launch them, it seems overkill to create two separate methods for them. My example is a bit clunky as well, but you’ll get my point from it.

Now, after having looked at your collision function a bit closer, it may just be that your function’s only issue is this line:

if self and ( other.type == "blob" or other.type == "enemy" ) then

Unless you have made some special arrangements, you don’t have “other.type”. In collision events, what you have by default should bee “event.other”, so you’d get the type from “event.other.type”.

Thanksss!! 

your code is more simple and efficient, but the bullets don’t appear now :frowning: and there is this error in runtime 

Bad argument #-1 to ‘addBody’ (Proxy expected, got nil)

 

File: scene/game/lib/bullet.lua

Line: 109

physics.start() local projectile = display.newImageRect( "scene/game/img/seme.png", w, h ) function projectile:fire( leftOrRight ) --projectile.alpha = 1 -- objects have alpha value of 1 by default, so this probably does nothing? --projectile.x=self.x -- this line seems to just set the object's x position to itself, i.e. does nothing. --projectile.y=self.y -- same as above physics.addBody( projectile, "dynamic", {isSensor=true, isBullet=true, bounce=0, density=2} ) projectile.gravityScale = 0 direction = self.flip if leftOrRight and leftOrRight == "left" then projectile.x = projectile.x - 100 projectile:setLinearVelocity( -800, 0 ) else projectile:setLinearVelocity( 800, 0 ) end timer.performWithDelay(2000, function() display.remove(projectile) end) end

this is my code now.

Thank you so much Xedur, you’re saving me!

Well, most I’m doing is just guessing based on quickly reading your code.

For instance, if I would create a firing function, I wouldn’t add methods to the projectile itself. I would create a function that simply:

  1. creates the projectile, i.e. the display object and its physics body,

  2. launches it using linear impulse (you don’t need a method for this, you could just check if your character/gun is facing left or right and use that),

  3. removes it upon collision or time out.

I am just seeing small parts of your code and it feels counter intuitive to me, based on this limited knowledge, I don’t understand why a projectile needs a method and why don’t you just fire it. Also, it is impossible for anyone to debug a runtime error based on the code that you’ve shown.

If you want more help, then I would recommend posting a small sample project that demonstrates your issue. By doing this, you often find out that you’ve solved your issue by yourself in the process.

ok , but what do you mean with sample project? 

Furthermore, how do i then call back the bullet function in my hero.lua?

 

function instance:fireLaser() if flip == 0.133 then self.bullet:fire("right") elseif flip == -0.133 then self.bullet:fire("left") end end

Thanks again

Sample project means that if you have a problem that you are experiencing and you need help with, then create a small Corona project that contains all of the necessary code (and possible other files) for others to run your code on their Corona simulators. That way they can actually see what you are seeing and they can help you more easily to solve your issue.

Mind you, however, that this sample project should be small and not your entire project. It should just contain the bare necessities required to demonstrate the issue that you are having.

Also, regarding your question about how to call back your bullet function in your file, the answer is that I don’t know. I don’t know what your hero.lua is, how it is written, etc. I barely know anything about your project or how it is written, so I cannot proficiently answer your question. If that method is attached to some object in your hero.lua file, then you’d just call it by “object:fireLaser”.

But really, if you need help with some issue other than your original question was here, then consider opening a new thread and including the sample project there.

In cases like this, it is best to create a small project that demonstrates your issue. The biggest issue here is that while we know how you are firing the bullet, we don’t know what you are firing the bullet at, i.e. we can’t know anything for certain about why your collisions aren’t working because we only have one of the two pieces that are supposed to collide.

There are also some issues in your function with how you create the projectile and how you could make your code easier. For instance, you are creating the display image twice, but you shouldn’t do that. Secondly, you don’t need to write the almost exact same function twice in a row. Just use one function and enter different values for some of the arguments/parameters.

Now, about your collision issue, one possible reason could be that you set “.isBullet” before the object actually has a physics body. I’m not sure if the order matters, but I would lean towards yes. Secondly, you fire the bullets at a crazy speed. Even if the projectile is a bullet, I’m not sure if it can detect a collision of your tiny projectile is travelling hundreds of pixels per second and it is supposed to hit a fairly small enemy.

Typically, in games, if you want to create guns that fire bullets at instant or near instant speed, you’d use a hit scan technique where you simply calculate if the bullet would hit at the time the gun was fired instead of actually shooting a projectile and seeing if it hits later.

ok, thanks…but what do you mean with small project? 
 

yes, but  if i create the display image once, corona report me an error with nil value on the projectile inside the functions…I know that the problem is there but I don’t know how resolve…

Thanks

Well, here’s just a small snipped and an example on how you could make the function a bit shorter.

function projectile:fire( leftOrRight ) --projectile.alpha = 1 -- objects have alpha value of 1 by default, so this probably does nothing? --projectile.x=self.x -- this line seems to just set the object's x position to itself, i.e. does nothing. --projectile.y=self.y -- same as above physics.addBody( projectile, "dynamic", {isSensor=true, isBullet=true, bounce=0, density=2} ) projectile.gravityScale = 0 direction = self.flip if leftOrRight and leftOrRight == "left" then projectile.x = projectile.x - 100 projectile:setLinearVelocity( -800, 0 ) else projectile:setLinearVelocity( 800, 0 ) end timer.performWithDelay(2000, function() display.remove(projectile) end) end

Since your fireLeft() and fireRight() methods only differences are the projectile’s initial x position and which way you launch them, it seems overkill to create two separate methods for them. My example is a bit clunky as well, but you’ll get my point from it.

Now, after having looked at your collision function a bit closer, it may just be that your function’s only issue is this line:

if self and ( other.type == "blob" or other.type == "enemy" ) then

Unless you have made some special arrangements, you don’t have “other.type”. In collision events, what you have by default should bee “event.other”, so you’d get the type from “event.other.type”.

Thanksss!! 

your code is more simple and efficient, but the bullets don’t appear now :frowning: and there is this error in runtime 

Bad argument #-1 to ‘addBody’ (Proxy expected, got nil)

 

File: scene/game/lib/bullet.lua

Line: 109

physics.start() local projectile = display.newImageRect( "scene/game/img/seme.png", w, h ) function projectile:fire( leftOrRight ) --projectile.alpha = 1 -- objects have alpha value of 1 by default, so this probably does nothing? --projectile.x=self.x -- this line seems to just set the object's x position to itself, i.e. does nothing. --projectile.y=self.y -- same as above physics.addBody( projectile, "dynamic", {isSensor=true, isBullet=true, bounce=0, density=2} ) projectile.gravityScale = 0 direction = self.flip if leftOrRight and leftOrRight == "left" then projectile.x = projectile.x - 100 projectile:setLinearVelocity( -800, 0 ) else projectile:setLinearVelocity( 800, 0 ) end timer.performWithDelay(2000, function() display.remove(projectile) end) end

this is my code now.

Thank you so much Xedur, you’re saving me!

Well, most I’m doing is just guessing based on quickly reading your code.

For instance, if I would create a firing function, I wouldn’t add methods to the projectile itself. I would create a function that simply:

  1. creates the projectile, i.e. the display object and its physics body,

  2. launches it using linear impulse (you don’t need a method for this, you could just check if your character/gun is facing left or right and use that),

  3. removes it upon collision or time out.

I am just seeing small parts of your code and it feels counter intuitive to me, based on this limited knowledge, I don’t understand why a projectile needs a method and why don’t you just fire it. Also, it is impossible for anyone to debug a runtime error based on the code that you’ve shown.

If you want more help, then I would recommend posting a small sample project that demonstrates your issue. By doing this, you often find out that you’ve solved your issue by yourself in the process.

ok , but what do you mean with sample project? 

Furthermore, how do i then call back the bullet function in my hero.lua?

 

function instance:fireLaser() if flip == 0.133 then self.bullet:fire("right") elseif flip == -0.133 then self.bullet:fire("left") end end

Thanks again

Sample project means that if you have a problem that you are experiencing and you need help with, then create a small Corona project that contains all of the necessary code (and possible other files) for others to run your code on their Corona simulators. That way they can actually see what you are seeing and they can help you more easily to solve your issue.

Mind you, however, that this sample project should be small and not your entire project. It should just contain the bare necessities required to demonstrate the issue that you are having.

Also, regarding your question about how to call back your bullet function in your file, the answer is that I don’t know. I don’t know what your hero.lua is, how it is written, etc. I barely know anything about your project or how it is written, so I cannot proficiently answer your question. If that method is attached to some object in your hero.lua file, then you’d just call it by “object:fireLaser”.

But really, if you need help with some issue other than your original question was here, then consider opening a new thread and including the sample project there.