Problem with detecting collision between circle and line.

I have

local line = display.newLine( sceneGroup, 0,_H-1, _W, _H-1)
    line:setStrokeColor(1,0,0,1)
    line.strokeWidth=8
    line.myName=“Floor”
    sceneGroup:insert(line)
    physics.addBody(line, “static”, {isSensor = True}) – I was reading add body and I thought that would help.

I copied this function from Nick Sherman (thanks Nick!)

function touchCircle(event)
    local obj = event.target
    local cid = obj.id
    local objective = obj.objective
    
    if event.phase == “began” then
        print (“Circle number " … cid … " was clicked!”)
        print ("objective is " … objective)
    end
    

I called that function with

c:addEventListener(“touch”, touchCircle)

So, right after c:addEventListener(“touch”, touchCircle)

I added

c:addEventListener(“collision”, CollisionWithLine)

Then I tried to add function just like he did but using the info from your documentation

function CollisionWithLine(event)
    local obj = event.target   – I will worry about these later.
    local cid = obj.id    – I will worry about these later.
    local objective = obj.objective  – I will worry about these later.
    

–I found out I had to put this in here because as soon as I created the circles this function was being called.  I assume collision with background??? but it was nil for object1.  No idea why.  But the problem is that when the circle touches the line I still get nothing in object1.  But then it does some strange things on my screen.  Likes stops but the text in the circle move backwards.  VERY strange.

    if (event.object1 == nil) then 
        print(“nothing in object1”)
        return false
    end
    if (event.object2 == nil) then
        print(“nothing in object2”)
        return false
    end
    
    if event.phase == “began” then
        print (“Circle number " … cid … " collided with line!”)
        print ("obj1 is " … event.object1.myName … " obj2 is " … event.object2.myName)
        print ("objective is " … objective)
    end
    
end
 

Any ideas what I am doing wrong?

Thanks!

I don’t think you can add a physics body to a line object. Instead try creating a long, thin rectangle.

Thanks for your reply Nick. I read this in the documentation. “You should not add a physics body to a line object created with display.newLine(), unless the body type is “static”.” I did make it static. Anyway I changed it. local floor = display.newImageRect(sceneGroup,“images/floor.png”,_W,2) floor.x=_W/2 floor.y=_H-1 floor.myName=“Floor” --didn’t know what to put here floor.id=“Floor” – didn’t really need this but I put it anyway. physics.addBody(floor, “static”) and I still get the SAME strange behavior.

Are both the circle and the rect inserted into the same display group?

Yes. I see it getting triggered. Just null is used. Here is my code - some stuff taken out. local floor = display.newImageRect(sceneGroup,“images/floor.png”,_W,2) – sceneGroup:insert(floor) ( I don’t think I need this, I tried both ways - with and without) physics.addBody(floor, “static”) level1b( sceneGroup, composer.objective, composer.gravity, composer.points) function level1b( group, objective, speed, points) … createCircle(group, 60*i+30,-60*j, 28, created, speed, objective) … end function createCircle(group, xCenter, yCenter, radius, created, speed, objective) local c = display.newCircle(group, xCenter, yCenter, radius) local choice=“Hello” local text = display.newText(group,choice,xCenter,yCenter,Helvetica, 12) physics.addBody(c, {density = 0.01, radius = radius, bounce = 0.0}) physics.addBody(text, {density = 0.01, radius = radius, bounce = 0.0}) c:setLinearVelocity(0,speed) text:setLinearVelocity(0,speed) c:addEventListener(“touch”, touchCircle) – to make it touchable c:addEventListener(“collision”, CollisionWithLine) – to make it check if collided. c.id = choice text.id = choice c.objective = objective c.myName = choice end function touchCircle(event) local obj = event.target local cid = obj.id local objective = obj.objective if event.phase == “began” then print (“Circle number " … cid … " was clicked!”) print ("objective is " … objective) end end function CollisionWithLine(event) local obj = event.target – will worry about this later local cid = obj.id – will worry about this later local objective = obj.objective – will worry about this later if (event.object1 == nil) then print(“nothing in object1”) – All I get back is this!!! return false end if (event.object2 == nil) then print(“nothing in object2”) return false end if event.phase == “began” then print (“Circle number " … cid … " collided with floor!”) print ("obj1 is " … event.object1.myName … " obj2 is " … event.object2.myName) print ("objective is " … objective) end end As soon as I create the circles, I get a Bunch of “nothing in object1” Then when the balls hit the bottom line I get “nothing in object1” Sorry for taking so much of your time. I am probably doing something stupid. :frowning: It just gets frustrating.

what is with the formatting?  It looked great when I typed it!!!  UGH!

You need to wrap code in lua tags.

Put [*lua*] (excluding the asterisks) before the code and [*/lua*] after the code.

Ok, trying to type it again. 

Yes. I see it getting triggered. Just null is used. Here is my code - some stuff taken out.

local floor = display.newImageRect(sceneGroup,“images/floor.png”,_W,2)

– sceneGroup:insert(floor) ( I don’t think I need this, I tried both ways - with and without)

physics.addBody(floor, “static”)

level1b( sceneGroup, composer.objective, composer.gravity, composer.points)

function level1b( group, objective, speed, points)

createCircle(group, 60*i+30,-60*j, 28, created, speed, objective)

end

function createCircle(group, xCenter, yCenter, radius, created, speed, objective)

local c = display.newCircle(group, xCenter, yCenter, radius)

local choice=“Hello”

local text = display.newText(group,choice,xCenter,yCenter,Helvetica, 12)

physics.addBody(c, {density = 0.01, radius = radius, bounce = 0.0})

physics.addBody(text, {density = 0.01, radius = radius, bounce = 0.0})

c:setLinearVelocity(0,speed)

text:setLinearVelocity(0,speed)

c:addEventListener(“touch”, touchCircle) – to make it touchable

c:addEventListener(“collision”, CollisionWithLine) – to make it check if collided.

c.id = choice

text.id = choice

c.objective = objective

c.myName = choice

end

function touchCircle(event)

local obj = event.target

local cid = obj.id

local objective = obj.objective

if event.phase == “began” then

print (“Circle number " … cid … " was clicked!”)

print ("objective is " … objective)

end

end

function CollisionWithLine(event)

local obj = event.target – will worry about this later

local cid = obj.id – will worry about this later local

objective = obj.objective – will worry about this later

if (event.object1 == nil) then

print(“nothing in object1”) – All I get back is this!!!

return false

end

if (event.object2 == nil) then

print(“nothing in object2”)

return false

end

if event.phase == “began” then

print (“Circle number " … cid … " collided with floor!”)

print ("obj1 is " … event.object1.myName … " obj2 is " … event.object2.myName)

print ("objective is " … objective)

end

end

As soon as I create the circles, I get a Bunch of “nothing in object1” Then when the balls hit the bottom line I get “nothing in object1” Sorry for taking so much of your time. I am probably doing something stupid. :frowning: It just gets frustrating.

ahhhh formatting problem because they use google tools.  I am in China behind the great wall of china and when I posted the previous post I was connected to VPN (not working at time).  This post was after VPN was working.  So, they must use googleapis.com or something for formatting that did not get called when I wrote the previous post without using VPN.  So, sorry for the previous mess.

I just tried adding this line

floor:addEventListener(“collision”, CollisionWithLine)

Still no help.

I guess it doesn’t matter which one we listen to.  It will just depend which one we want to be object1, right?

event.object1 and event.object2 are only for use with runtime collision listeners. Local collision listeners, which you are using here, use event.target for the object that was hit (i.e. the object that had a collision listener applied to it), and event.other for the object that collided with it.

Thank you SOOO much!  That worked perfectly! 

I read in there -

When the event is detected with a table listener within an object, certain properties are replaced:

  • object1 → target
  • object2 → other
  • element1 → selfElement
  • element2 → otherElement

But, can you explain what a runtime listener is? 

Thank you once again!

A runtime listener runs across all objects, waiting for a collision between any two objects. Using a local collision listener allows you to be more targeted in terms of what collisions you do and don’t want to track.

An example would be the rings in Sonic The Hedgehog. When he gets hit and they fly all over the place, you wouldn’t want a listener to be running every time the rings collided with each other or platforms, enemies etc. It would just slow everything down.

So you’d put a local listener on Sonic and say ‘If sonic gets hit by a ring, collect the ring’.

Thank you!

Two more questions if I may bother you.

I am trying to learn destroy method, but having trouble getting it to work.  So, for right now, I just made the object invisible.

However, the BIGGER problem I am having is the text inside the circle.

I figured out the immediate collisions were caused by the text being inside the circle.

Which is fine.  I fixed it by checking if the id’s were the same I ignored the collisions.

The problem is this…

physics.addBody(c, {density = 0.01, radius = radius, bounce = 0.0})

physics.addBody(text, {density = 0.01, radius = radius, bounce = 0.0})

When the circle hits the bottom it disappears.  Great.  However, the text has stopped moving because the circle stopped moving (so it won’t hit the floor).  I am not able to try to reference the text by its .id

Example I tried using id from c to make text.id invisible but couldn’t do it from inside the listener.

Is there a way to make those 2 things a NEW GROUP.  Example: Something like this…

smallGroup:insert©

smallGroup:insert(text)

Then do physics.addBody(smallGroup, …)

I already tried it - didn’t work, but that would be ideal, then I can make the smallGroup invisible and then delete it.

Thanks!

This is the code I tried to destroy the obj

I put this inside function CollisionWithLine(event)

local function removeObject()
        display.remove(event.obj)
    end

timer.performWithDelay(1, removeObjects, 1)

Yes, you want to make your circle object and text a group, and then make that a physics object. Create your circle and text objects then:

[lua]

local g = display.newGroup()

g:insert©

g:insert(text)

physics.addBody(g, {density = 0.01, radius = radius, bounce = 0.0})

g:addEventListener(“collision”,collisionWithLine)

g.id = choice

g.objective = objective

g.myName = choice

group:insert(g)

[/lua]

In your removal code, you called the function removeObject then called it using removeObjects.

That corrected, the object removal code should work (I think), maybe put a longer delay, say 50ms? And remember to make event.obj = nil.

[lua]  VPN not working so let’s see if I can format this response or not.

I am about to pull my hair out!  I am trying to learn from what you wrote and run with it.  It worked great with the touch event (making the circle and text into g).  If I touch one circle that one circle disappears (circle and text)- GREAT!  but, for the other event if collision with line then they ALL disappear instantly.

According to messages I print.  It appears as though, as soon as the first circle touches the line, then all circles touch the line!  So, it is as if g is being done for ALL circles for the collision event instead of different g.  Yet, it worked fine for the touch event.

Any ideas?  I am not going to post my code, because a) almost identical to above and b) VPN not working so I don’t know if this will format well.

[/lua]

Put the code in the lua tags as I mentioned above, and paste in from your code editor. That will help with the formatting.

[lua] function CollisionWithLine(event) local obj = event.target local cid = obj.id local objective = obj.objective local targ = event.other if ( obj == nil) then print(“nothing in obj”) return false end if ( targ == nil) then print(“nothing in targ”) return false end if targ.myName == obj.myName then print(“Ignore - circle and text hitting each other”) – should no longer happen but did twice out of 100. return false end if event.phase == “began” then if targ.myName == “Floor” then print (“Circle number " … cid … " collided with floor!”) print ("obj1 is " … targ.myName … " obj2 is " … obj.myName) print ("objective is " … objective) – then remove the object after 1 cycle local function removeObject() obj.isVisible = false display.remove(obj) obj = nil end timer.performWithDelay(50, removeObject, 1) end end function touchCircle(event) local obj = event.target local cid = obj.id local objective = obj.objective if event.phase == “began” then print (“Circle number " … cid … " was clicked!”) print ("objective is " … objective) obj.isVisible = false end end then inside my create circle function g:insert© text:setTextColor(0,0,1,255) g:insert(text) physics.addBody(g, {density = 0.01, radius = radius, bounce = 0.0}) g:setLinearVelocity(0,speed) g:addEventListener(“touch”, touchCircle) – to make it touchable g:addEventListener(“collision”, CollisionWithLine) – to make it check if collided. g.id = choice g.objective = objective g.myName = choice [/lua] So, as you can see, the 2 listeners were setup with the same call (using g). Thanks for your help!

well, I thought I would be smart and make an array of g, but even that didn’t matter! SOMETHING crazy is going on. As soon as touched the line all the circles disappeared. Yet, it worked with touch. I can understand if they BOTH didn’t work, but for one to work and the other not?