Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Help me with a bullet collision problem ! pls
Started by andrea.marrocco95 Aug 11 2019 08:55 AM

- - - - -
7 replies to this topic
[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

andrea.marrocco95

[GLOBAL: userInfoPane.html]
andrea.marrocco95
  • Observer

  • 6 posts
  • Corona SDK

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!



[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 822 posts
  • Corona SDK

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.



[TOPIC: post.html]
#3

andrea.marrocco95

[GLOBAL: userInfoPane.html]
andrea.marrocco95
  • Observer

  • 6 posts
  • Corona SDK

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



[TOPIC: post.html]
#4

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 822 posts
  • Corona SDK

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".


  • andrea.marrocco95 likes this

[TOPIC: post.html]
#5

andrea.marrocco95

[GLOBAL: userInfoPane.html]
andrea.marrocco95
  • Observer

  • 6 posts
  • Corona SDK

Thanksss!! 

your code is more simple and efficient, but the bullets don't appear now :( 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!



[TOPIC: post.html]
#6

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 822 posts
  • Corona SDK

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.


  • andrea.marrocco95 likes this

[TOPIC: post.html]
#7

andrea.marrocco95

[GLOBAL: userInfoPane.html]
andrea.marrocco95
  • Observer

  • 6 posts
  • Corona SDK

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



[TOPIC: post.html]
#8

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 822 posts
  • Corona SDK

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.




[topic_controls]
[/topic_controls]