Quick Links: Download Gideros Studio | Gideros Documentation | Gideros community chat | DONATE
Collision detection — Gideros Forum

Collision detection

QuasarCreatorQuasarCreator Member
edited July 2012 in General questions
Hi, I am currently trying to add a collision detection between my shapes so I can keep track of how many shapes are "connected".

currently my code looks like this:
 
--******************************************************************************
-- MY BODIES
--*****************************************************************************
	local function createSmallBox(x, y, name)
		smallbody = world:createBody{type = b2.DYNAMIC_BODY, position = {x = event.x, y = event.y}}
 
		smallbody.name = name
 
		smallShape = b2.PolygonShape.new()
		smallShape:setAsBox(20, 20)
		smallbody:createFixture{shape = shape, density = 1, restitution = 0.2, friction = 0.3}
 
		rec_small = Bitmap.new(Texture.new("images/rec_small.png"))
		rec_small:setAnchorPoint(0.5, 0.5)
		rec_small:setPosition(150, 150)
 
		left_joint = Bitmap.new(Texture.new("images/left_joint.png"))
		left_joint:setAnchorPoint(0.5, 0.5)
		left_joint:setPosition(150, 150)
 
		vertical_rec_small = Bitmap.new(Texture.new("images/vertical_rec_small.png"))
		vertical_rec_small:setAnchorPoint(0.5, 0.5)
		vertical_rec_small:setPosition(150, 150)
 
		vertical_right_joint = Bitmap.new(Texture.new("images/vertical_right_joint.png"))
		vertical_right_joint:setAnchorPoint(0.5, 0.5)
		vertical_right_joint:setPosition(150, 150)
 
		shapes[body] = rec_small
		shapes[body] = left_joint
		shapes[body] = vertical_rec_small
		shapes[body] = vertical_right_joint
	end
 
	local function createMediumBox(x, y, name)
		mediumbody = world:createBody{type = b2.DYNAMIC_BODY, position = {x = event.x, y = event.y}}
 
		mediumbody.name = name
 
		mediumShape = b2.PolygonShape.new()
		mediumShape:setAsBox(40, 20)
		mediumbody:createFixture{shape = shape, density=1, restitution = 0.2, friction = 0.3}
 
		rec_medium = Bitmap.new(Texture.new("rec_medium"))
		rec_medium:setAnchorPoint(0.5, 0.5)
		rec_medium:setPosition(150, 150)
 
		shapes[body] = rec_medium
 
	end
 
--****************************************************************************
-- shape buttons with their event listeners to limit the number of shapes
--****************************************************************************
 
	rec_smallBnt:addEventListener("click",
		function()
			--limiting to only 2 small rectangles
			x = x - 1
 
			if x > 0 then 
 
			rec_small.isFocus = false
 
			--add the event listeners for the new rectangle
			rec_small:addEventListener(Event.MOUSE_DOWN, onMouseDown, rec_small)
			rec_small:addEventListener(Event.MOUSE_MOVE, onMouseMove, rec_small)
			rec_small:addEventListener(Event.MOUSE_UP, onMouseUp, rec_small)
			--adding the rectangle to the stage
			self:addChild(rec_small)
 
			end
		end
	)
 
--/////////////////////////////////////////////////////////////////////////////////////////////////////
 
	rec_mediumBnt:addEventListener("click",
		function()
			--limiting to only 2 shapes
			y = y - 1
 
			if y > 0 then 
			rec_medium.isFocus = false
 
			--add the event listeners for the new rectangle
			rec_medium:addEventListener(Event.MOUSE_DOWN, onMouseDown, rec_medium)
			rec_medium:addEventListener(Event.MOUSE_MOVE, onMouseMove, rec_medium)
			rec_medium:addEventListener(Event.MOUSE_UP, onMouseUp, rec_medium)
			--adding the rectangle to the stage
			self:addChild(rec_medium)
 
 
			end
		end
	)
 
--******************************************************************
-- MY COLLISION FUNCTION
--*****************************************************************
local flow = 0
for i = 0, 8 do
	local function onBeginContact(event)
		--you can get the fixtures and bodies in this contact like:
		local fixtureA = event.fixtureA
		local fixtureB = event.fixtureB
		local bodyA = fixtureA:getBody()
		local bodyB = fixtureB:getBody()
 
		print("collision!!")		
		flow = flow + 1
	end
end
if flow == 8 then
	print("game is over")
end

So, in this code I split my bodies into two categories: 1. small bodies (40X40 square) and 2. medium bodies (80X20) then later I will add large bodies. I put all my shapes into those two categories. Then when a button is hit. For example, the small rectangle button is hit then a small rectangle is spawned. I put self:addChild(rec_small) in the button's event listener but I get an error saying:
level1.lua:315: attempt to index global 'rec_medium' (a nil value)
stack traceback:
	level1.lua:315: in function <level1.lua:310>
I don't quite understand why I can't use rec_medium when I was declared in an earlier function.
Also, before I was getting that error my shapes wouldn't detect collisions with each other. Is there any reason why you would say that was happening?

Thank you so much!!! I appreciate the help! :D

Dislikes: ___, Yan

I am a programming noobie, so thanks in advance for helping me out and answering my questions!
+1 -1 (+0 / -2 )Share on Facebook

Comments

  • twisttaptwisttap Member
    edited July 2012
    If you could provide the project files it may be more useful. I don't see you have create the buttons you added Listeners to and also why did you add eventListeners inside listeners ?

    Likes: QuasarCreator

    +1 -1 (+1 / -0 )Share on Facebook
  • @twisttap- Thanks for the comment! My buttons are just simple button functions but I will add one button to the code once I get to my computer. I added event listeners inside the linstener because the user will be able to move the shape with their finger.
    I am a programming noobie, so thanks in advance for helping me out and answering my questions!
  • I think you've got this whole event listener thing a bit confused.

    In your situation you'll be better off adding a single event listener to the stage (or the main controller object for this screen). Then in that listener (during the press phase) you check ALL the current buttons to see which one is touched (using the sprite:hitTestPoint() function), you would then store a reference to the button (effectively giving it focus) - and then in the move phase you simply reset the currently focused button to the current event x,y positions, and then lastly when you receive the release event just release the button and do what ever checks to line up or connect each button as required.

    Likes: QuasarCreator

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 )Share on Facebook
  • QuasarCreatorQuasarCreator Member
    edited July 2012
    @techdojo Thanks for the comment! I really appreciate the help!
    :D

    So, basically I have been confused with the event listeners so thanks for clearing that up, but I can move the object around fine with a touch and haven't had any problems with that. So, I am guessing that what you wrote would be a much more efficient or better style of programming right?
    It is my collision detection that I am having a problem with. I am trying to detect the collisions between my shapes. However, I am confused about how I should organize all my bodies and how I can spawn my shape or body when the button is pressed. Also, I have a feeling my onBeginContact function is wrong because there are two categories of sprites.


    I think I have bitten off more than I can chew with this project!
    I am a programming noobie, so thanks in advance for helping me out and answering my questions!
  • No worries - if you feel the need to you might want to back up a bit and try implementing the first stage and then adding elements bit by bit.

    I always apply the KISS principal (Keep it simple stupid) as much as possible, too often people want to over complicate things just because they think they can or they want to show off (not saying that's what's happening here - just that it happens, a lot, especially with programmers who think they're more experienced than they are).

    However one thing that confuses me - are you talking about bog standard rectangle shapes here? why are you using physics, if it's just for collision then you'll find it a lot easier to remove all of that and start again from first principals.

    Likes: QuasarCreator

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 )Share on Facebook
  • QuasarCreatorQuasarCreator Member
    edited July 2012
    @techdojo Thanks for the advice. The first time I heard of KISS was when I was watching the Office
    :-))

    So, my shapes are basically just images. I am just trying to detect when they collide. I don't want them to be bouncing around when they collide or anything of that sort.
    I am a programming noobie, so thanks in advance for helping me out and answering my questions!
  • Then the physics is definitely overkill - just use a simple bounding box test to see if two sprites overlap.

    On side note the first time I heard KISS was when they were playing "Crazy Crazy Nights", but that's not really relevant right now :)

    Likes: QuasarCreator

    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
    +1 -1 (+1 / -0 )Share on Facebook
  • ar2rsawseenar2rsawseen Maintainer
    edited July 2012
    Yeah, but what about if sprites are transformed (scaled, rotated, skewed :) )?
    I guess not in this situation, but what if?

    BTW about checking bounding box, check this thread:
    http://www.giderosmobile.com/forum/discussion/comment/8332#Comment_8332

    Likes: QuasarCreator

    +1 -1 (+1 / -0 )Share on Facebook
  • QuasarCreatorQuasarCreator Member
    edited July 2012
    @ar2rsawseen Thanks for the link!

    I added the piece of code, however, I am still not get any collision feedback. So, I don't think I did this properly. I mean how could I do this wrong its seems so simple.
     
    --Input (sprite2): another sprite to check for collision detection
    --Return: return true if the rectangles overlap otherwise return false
    function Sprite:collision(sprite2)
    	local flow = 0
     
    	-- self bottom < other sprite top
    	if self:getY() + self:getHeight() < sprite2:getY() then
    		flow = flow + 1
    		print("collision")
    		print("flow = " .. flow)
    		return false
    	end
    	-- self top > other sprite bottom
    	if self:getY() > sprite2:getY() + sprite2:getHeight() then
    		flow = flow + 1
    		print("collision")
    		print("flow = " .. flow)
    		return false
    	end
    	-- self left > other sprite right
    	if self:getX() > sprite2:getX() + sprite2:getWidth() then
    		flow = flow + 1
    		print("collision")
    		print("flow = " .. flow)
    		return false
    	end
    	-- self right < other sprite left
    	if self:getX() + self:getWidth() < sprite2:getX() then
    		flow = flow + 1
    		print("collision")
    		print("flow = " .. flow)
    		return false
    	end
     
    	if flow == 7 then
    		print("game is over")
    	end
     
    	return true
    end
    I not getting any errors. Just nothing is printing on the terminal. I placed this function at the end of my game.lua. Any idea what it could be?

    --Thanks!
    I am a programming noobie, so thanks in advance for helping me out and answering my questions!
  • ar2rsawseenar2rsawseen Maintainer
    edited July 2012
    I really don't know the structure of your code
    But if you are inheriting from Sprite, then you should put this code before the inheritance. Or you should define this as a method for your own class, and then use it on other object's.

    I'ts really hard to tell, what is wrong, if you don't see whole code, sorry ;)
  • @ar2rsawseen Thanks for the comment. Can I send you my level1.lua file, so you can have a quick look at it? Just to let you know that my code will look like crap and I hope it is readable. :-)) I hope I am not asking for too much!
    :-bd

    --Thanks in advance! ^:)^
    I am a programming noobie, so thanks in advance for helping me out and answering my questions!
  • ar2rsawseenar2rsawseen Maintainer
    Sure, you could also post it here, you'll get much more feedback and opinions from whole community, rather from one person.
    But if for some reason, you don't feel like posting it here, you can email it to me.
    Put my nickname in front of gmail.com ;)
Sign In or Register to comment.