Collision events for newLine not working since build 2017.3068?

Since I updated to build 2017.3068, collision detection for newLine is not working. I had a section in my code that detected a collision between an image and a line but now the event is no longer triggered. I have tried to change the newLine to another image object (no other changes in the code) and then it works fine.

Anyone else had any problems with this in a recent build?

This is how the line is created:

local myLine = display.newLine(x1, y1, x2, y2) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody(myLine, "static", { friction = 0.0, bounce = 0.0, isSensor = true })

1, Have you verified the position of the body by using hybrid draw mode?  If not,please do.  It seems fine to me:
 

local physics = require "physics" physics.start() physics.setGravity(0,0) physics.setDrawMode('hybrid') -- \<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\< Always do this to validate body position local points = { 100, 100, 200, 100} local myLine = display.newLine( unpack(points) ) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody(myLine, "static", { friction = 0.0, bounce = 0.0, isSensor = true })

2.Even if the body is in the right place, a thin body like that is going to cause you troubles because it is highly susceptible to tunneling.

** UPDATE: This may not be true any longer.  I suspect lines automatically use a chain body. **

  1. You shouldn’t really be adding ‘generic’ bodies to lines, whether they worked for you before or not.  This is not the intended usage of lines and a common mistake.

** UPDATE: May be moot (see my post below) ** 
4. However, you can add a chain style body: 
https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#edge-shape-chain-body

local physics = require "physics" physics.start() physics.setGravity(0,0) physics.setDrawMode('hybrid') local points = { 100, 100, 150, 150, 200, 100} local points2 = { 0, 0, 50, 50, 100, 0} local myLine = display.newLine( unpack(points) ) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody( myLine, "static", { chain= points2, connectFirstAndLastChainVertex = false, friction = 0.0, bounce = 0.0, isSensor = true } )

@staff,

I made an assertion above #3, but I am no-longer correct about this

In fact I suspect that there was an under-the-hood change I missed.

If we add ‘generic’ bodies to lines, does it automatically default to a chain body?

I ask because this looks suspiciously like a open chain body:

local points = { 100, 100, 150, 150, 200, 100, 250, 250, 100, 300 } local myLine = display.newLine( unpack(points) ) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody(myLine, "static", { friction = 0.0, bounce = 0.0, isSensor = true })

Hi @Divergent Monkey,

I just tested your code (basically the same) and it works fine in 2017.3068. I drop a reasonably-sized “box” through the line and it triggers a collision event, exactly as expected. Not sure what happened but please check that your code hasn’t undergone any other changes that might have affected this.

That being said, like @roaminggamer, I discourage using physics on newLine() objects. Yes it’s allowed, but I avoid doing so within my own code and I don’t recommend the practice in general. Basically, it’s just too prone to various issues like thin-line tunnelling, the body must be static, and chain shapes are a magnitude of times more powerful and flexible, so I don’t find a reason to combine physics and newLine() objects.

Best regards,

Brent

Hello,

@roaminggamer:  I have verified the position of the body by using hybrid draw mode and I have ruled out tunneling by letting the object that is supposed to collide with the line hover directly on it. Still, no collision detection.

@brent: I have rechecked my other code but none of it that could have an effect on this has changed. The only thing that changed is updating to 2017.3068.

@both: if using physics on newLine() objects is discouraged, I will not use it of course (even though it worked before). I looked at your solution using chain shapes. I copied the example in the tutorial (linked by roaminggamer above) but strangely enough, that did not trigger a collision event either. I tried to change the chain part to a simple rectangular body and then it worked fine.

In the same place in the code, if I add any kind of object with a rectangularor circular body, it works fine. If I change the body to a chain shape it stops working. When using hybrid draw mode, I can see that the “body area” is only outlined but not colored green as when using e.g. rectangular bodies.

Background: in my game, there are non-moving lazer beams (displayed as newLine() objects with different rotations). If the space ship hits the lazer beam, it is supposed to explode. 

Even though I am still curious about why I got the results above, I have solved the issue by creating an image 100 x 2 representing the lazer beam, then calculating the distance and angle between the two points where the lazer beam should start and end on the screen. The width and rotation is then applied on the image, which also has a simple rectangular physics body. Visually and mechanically, this produces the exact same result as using a line (if the physics stuff had worked, that is).

Hi @Divergent Monkey,

What exact build before 3068 was the behavior different? If you’d like to send me a very simple test case which shows this behavior, I’ll compare it between builds. My simple test case showed correct collision on the newLine() object, but I can take a look at your case if you’d like: brent (at) coronalabs (dot) com.

Thanks,

Brent

@Brent: unfortunatelly, I do not know which version I used before but it was a daily build, not an official release. Since I dropped the newLine() solution for the image solution (see previous post) I no longer have the malfunctioning code to produce a test case.

However, the newLine() object I created was exactly as described in my first post, and the object colliding with it was the following:

 local lander = display.newSprite(landerSpriteSheet, landerSequences) lander:addEventListener("sprite", landerAnimationListener) lander.x = landerXPos lander.y = landerYPos lander.isFixedRotation = true lander.isBullet = true lander.collision = onLanderCollision lander:addEventListener("collision", lander) local landerOutlineChain = { -10, 59, -10, 41, -33, 41, -30, -45, 0, -59, 30, -45, 33, 41, 10, 41, 10, 59 } physics.addBody(lander, "dynamic", { density = 10.0, friction = 0.0, bounce = 0.0, chain = landerOutlineChain, connectFirstAndLastChainVertex = true }) lander.gravityScale = 0.0

Hope this is enough to somehow reproduce it. Thanks for your time!

Hi again,

I tested this further and I didn’t get a collision event in either the past public release (2016.2992) or in the new one (2017.3068).

I’m not sure I’ve ever seen implementation of chain shapes trying to collide with a line object. There might be some underlying Box2D thing which frowns upon that practice. I understand that you used a chain shape because the “lander” shape has concave bends, but I personally would have opted for a 2-element normal body… typically, I only use chain shapes for forming slopes, hills, and other curved bodies with a lot of distance, because chain shapes can have a large amount of segments.

Brent

Hello,

That’s really weird, it worked perfectly well before I updated to 3068… Either way, I am now using an image instead of a newLine() object and that works fine.

Question: is there a performance issue with chain shapes? Would a 2 element normal body be more efficient in terms of performance?

A chain shape with a “reasonable” number of vertices should perform just fine. I put “reasonable” in quotes because it’s just the nature of the beast with physics and some other things (particle generators, etc.) that you can exceed a practical, logical amount of anything. For example, I could probably trace a simulated 50 kilometers of 2D ground in a side-scroller with a single chain shape, because there isn’t a defined limit to the number of vertices, but that doesn’t mean that I should… and only by testing on real devices would I know that I’ve exceeded the “reasonable” limit. :slight_smile:

Brent

Ok, I see. In that case, I will check if I can reach the same result by using a multielement normal body instead. Thanks!

1, Have you verified the position of the body by using hybrid draw mode?  If not,please do.  It seems fine to me:
 

local physics = require "physics" physics.start() physics.setGravity(0,0) physics.setDrawMode('hybrid') -- \<\<\<\<\<\<\<\<\<\<\<\<\<\<\<\< Always do this to validate body position local points = { 100, 100, 200, 100} local myLine = display.newLine( unpack(points) ) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody(myLine, "static", { friction = 0.0, bounce = 0.0, isSensor = true })

2.Even if the body is in the right place, a thin body like that is going to cause you troubles because it is highly susceptible to tunneling.

** UPDATE: This may not be true any longer.  I suspect lines automatically use a chain body. **

  1. You shouldn’t really be adding ‘generic’ bodies to lines, whether they worked for you before or not.  This is not the intended usage of lines and a common mistake.

** UPDATE: May be moot (see my post below) ** 
4. However, you can add a chain style body: 
https://docs.coronalabs.com/guide/physics/physicsBodies/index.html#edge-shape-chain-body

local physics = require "physics" physics.start() physics.setGravity(0,0) physics.setDrawMode('hybrid') local points = { 100, 100, 150, 150, 200, 100} local points2 = { 0, 0, 50, 50, 100, 0} local myLine = display.newLine( unpack(points) ) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody( myLine, "static", { chain= points2, connectFirstAndLastChainVertex = false, friction = 0.0, bounce = 0.0, isSensor = true } )

@staff,

I made an assertion above #3, but I am no-longer correct about this

In fact I suspect that there was an under-the-hood change I missed.

If we add ‘generic’ bodies to lines, does it automatically default to a chain body?

I ask because this looks suspiciously like a open chain body:

local points = { 100, 100, 150, 150, 200, 100, 250, 250, 100, 300 } local myLine = display.newLine( unpack(points) ) myLine:setStrokeColor(1.0, 0.0, 0.0) myLine.strokeWidth = 2 physics.addBody(myLine, "static", { friction = 0.0, bounce = 0.0, isSensor = true })

Hi @Divergent Monkey,

I just tested your code (basically the same) and it works fine in 2017.3068. I drop a reasonably-sized “box” through the line and it triggers a collision event, exactly as expected. Not sure what happened but please check that your code hasn’t undergone any other changes that might have affected this.

That being said, like @roaminggamer, I discourage using physics on newLine() objects. Yes it’s allowed, but I avoid doing so within my own code and I don’t recommend the practice in general. Basically, it’s just too prone to various issues like thin-line tunnelling, the body must be static, and chain shapes are a magnitude of times more powerful and flexible, so I don’t find a reason to combine physics and newLine() objects.

Best regards,

Brent

Hello,

@roaminggamer:  I have verified the position of the body by using hybrid draw mode and I have ruled out tunneling by letting the object that is supposed to collide with the line hover directly on it. Still, no collision detection.

@brent: I have rechecked my other code but none of it that could have an effect on this has changed. The only thing that changed is updating to 2017.3068.

@both: if using physics on newLine() objects is discouraged, I will not use it of course (even though it worked before). I looked at your solution using chain shapes. I copied the example in the tutorial (linked by roaminggamer above) but strangely enough, that did not trigger a collision event either. I tried to change the chain part to a simple rectangular body and then it worked fine.

In the same place in the code, if I add any kind of object with a rectangularor circular body, it works fine. If I change the body to a chain shape it stops working. When using hybrid draw mode, I can see that the “body area” is only outlined but not colored green as when using e.g. rectangular bodies.

Background: in my game, there are non-moving lazer beams (displayed as newLine() objects with different rotations). If the space ship hits the lazer beam, it is supposed to explode. 

Even though I am still curious about why I got the results above, I have solved the issue by creating an image 100 x 2 representing the lazer beam, then calculating the distance and angle between the two points where the lazer beam should start and end on the screen. The width and rotation is then applied on the image, which also has a simple rectangular physics body. Visually and mechanically, this produces the exact same result as using a line (if the physics stuff had worked, that is).

Hi @Divergent Monkey,

What exact build before 3068 was the behavior different? If you’d like to send me a very simple test case which shows this behavior, I’ll compare it between builds. My simple test case showed correct collision on the newLine() object, but I can take a look at your case if you’d like: brent (at) coronalabs (dot) com.

Thanks,

Brent

@Brent: unfortunatelly, I do not know which version I used before but it was a daily build, not an official release. Since I dropped the newLine() solution for the image solution (see previous post) I no longer have the malfunctioning code to produce a test case.

However, the newLine() object I created was exactly as described in my first post, and the object colliding with it was the following:

 local lander = display.newSprite(landerSpriteSheet, landerSequences) lander:addEventListener("sprite", landerAnimationListener) lander.x = landerXPos lander.y = landerYPos lander.isFixedRotation = true lander.isBullet = true lander.collision = onLanderCollision lander:addEventListener("collision", lander) local landerOutlineChain = { -10, 59, -10, 41, -33, 41, -30, -45, 0, -59, 30, -45, 33, 41, 10, 41, 10, 59 } physics.addBody(lander, "dynamic", { density = 10.0, friction = 0.0, bounce = 0.0, chain = landerOutlineChain, connectFirstAndLastChainVertex = true }) lander.gravityScale = 0.0

Hope this is enough to somehow reproduce it. Thanks for your time!

Hi again,

I tested this further and I didn’t get a collision event in either the past public release (2016.2992) or in the new one (2017.3068).

I’m not sure I’ve ever seen implementation of chain shapes trying to collide with a line object. There might be some underlying Box2D thing which frowns upon that practice. I understand that you used a chain shape because the “lander” shape has concave bends, but I personally would have opted for a 2-element normal body… typically, I only use chain shapes for forming slopes, hills, and other curved bodies with a lot of distance, because chain shapes can have a large amount of segments.

Brent