Issues with collisions and high speeds

Hi,
 
I tried to increase the speed of my game using physics.setScale. Everything was feeling sluggish otherwise.
 
Here is a sample code. If anyone would be so kind to try and explain to me:
 

  1. Why does the ball go through the platform?
    I get the following console output:
     

platform height: 450
ball height: 428.65112304688

which indicates that the ball is still over the platform when the event is fired. The first thing we do is to set isSensor = false.
 
 
2. Why do none of the following options

  • isBullet = true     – (tried on ball and/or platform)
  • physics.setContinuous(enabled)
  • physics.setPositionIterations(300)
  • physics.setVelocityIterations(300)

seem to have any effect on the collision detection? Whatever combination of the above I use, the ball’s height is exactly the same to the billionth of pixel when the event is fired.
If any of the options could affect positively the detection of collision thanks to “real time detection” instead of “frame” detection, I believe the height would be different. 
 
The only option that had a tiny impact was fps = 60 instead of 30, but the ball stills goes through.
 
Thanks
endy

[lua]local physics = require(“physics”)
physics.start()

– physics.setPositionIterations( 300 )
– physics.setVelocityIterations( 300 )
– physics.setContinuous(enabled)

physics.setGravity(0,9.8)
local jumpPlatform = display.newRect( 120, 450, 100, 20 )
local ball = display.newCircle(150,350,20)

---- case 1: low speed. Works as expected
– physics.setScale(60)
– physics.addBody( ball, “dynamic”, { friction=0.2,density = 1.2} )

---- case 2: high speed, ball goes through
physics.setScale(300)
physics.addBody( ball, “dynamic”, { friction=0,density = 9} )

physics.addBody( jumpPlatform, “static”, { friction=0,isSensor = true} )
– jumpPlatform.isBullet = true
– ball.isBullet = true

function onFloorCollision(self,event )

if event.phase == “began” then
print(“platform height:”, self.y)
print(“ball height:”, event.other.y)
self.isSensor = false
self:setFillColor( 1,0,0 )
end
end

jumpPlatform.collision = onFloorCollision
jumpPlatform:addEventListener( “collision”, jumpPlatform )
 

ball:applyLinearImpulse(0, -1, ball.x, ball.y)[/lua]

Honestly, I would not adjust the physics scaling. I’ve never done it so I can’t advise on that.

However, if things need speeding up you can reduce the linear and angular damping (if there is any to begin with.) You can also reduce the density of objects.

If objects are moving too fast to collide with other objects it could be that they’re going too fast and you need to use object.isBullet=true

Hi Horace,

I did not know about the damping properties. I will try them and let you know. 

edit: nevermind, I just checked the damping doc and it says default value is 0 and I was not setting anything.

They do collide, and in time, since at the time of collision the ball is still above the platform, I just understand why the ball still goes through the platform. Also as mentioned in OP, I already tried isBullet=true, it has no effect at all.

Thanks

endy

Hi @endy,

Just to confirm, are you getting a collision event when the ball hits the platform? We need to rule that out first. If you’re getting the collision event reported, then at least we know it’s not an issue with how you’re handling the collision.

Brent

Hi Brent,

Yes, a collision is detected (I get the console output giving me the height of the ball and the platform)

It looks like setting isSensor=false is lagging.

Thanks

endy
 

Hi @endy,

So if I understand your intention, when the ball is coming from one side (above or below, not sure which), you want to have it pass through the platform, but not vice-versa? Thus, you change it to a non -sensor (.isSensor=false) in that case?

For one-sided platforms, you should really explore the PRE-collision event. I posted a tutorial on this very topic awhile back, and it includes a sample project which you can explore the code for.

http://coronalabs.com/blog/2012/11/27/introducing-physics-event-contact/

Brent

Hi Brent, 

That’s right.

Ok, so the whole story is that last week I started with your tutorial and it worked pretty well. Except that all the physics seemed sluggish (I am not using any damping just to be clear) so I increased physics.setScale which gave me the very dynamic game play I wanted. Except that now, once in around 50 collisions (precollisions) the character bounces on the platform instead of going through. After a lot of testing, it seems that event.contact.isEnable = false is lagging a bit, and by the time it becomes effective, the character has already bounced back.

So I decided to go through all Corona physics doc again and noticed the isSensor property which seemed could be used for jump through platforms. I decided to build a very simple demo that I posted above with isSensor, and noticed that I was also facing some issues in a high speed context. In the demo I posted in OP, it feels like isSensor = false is lagging too.

I am new to Corona and I really like it, however I need to make sure that I can achieve proper collisions handling in a high speed context before going further (ie: buying pro version).

Also just for the sake of improving my Corona skills, I would really like to understand the issue in question 2 of my OP (why none of the options for real time detection have any impact on the collision detection).

Alternatively, if you have a way to increase game speed without changing physics.setScale(), that would be fine too.

Sorry for the wall of text I just want to make sure everything is clear.

Thanks

endy

because your wall is a sensor (see line 15).  you can change every other setting ad nauseam and your ball will still NEVER react to a collision with a sensor - because that’s what sensors DO.  when you receive the collision event it’s too late to change to isSensor=true/false for THIS collision.  (and in general you shouldn’t be changing physical properties DURING a collision)  set isSensor=false on line 15 and you’ll start getting your collision reactions.  if you want it to be conditional then you should instead listen for the PRE collision event and set contact.isEnabled true/false as needed.  hth

Hi Dave,

Ok for isSensor, I will go back to my previous implementation with isEnabled. I just recall many tutorials for jump through platforms that were using isSensor, but they may be outdated. Thanks for the advice. By the way in my demo, using isSensor works very well with a physics scale of 80, it just doesn’t work when the scale is very high.

I still need a way to make the game faster, with preCollision and isEnabled, my character doesn’t go through the platform in around 2% of the cases, and I have a strong feeling it is because I am using physics.setScale(300). None of the options for fast objects collisions have any effect.

Thanks

endy

IF your ball is moving slowly enough to not entirely pass through the sensor in this step, then it might “seem” like your code is working.  but what would really happen is the ball would react during a NEW collision that occurs NEXT frame (to what is now a non-sensor platform)

(and you’ll potentially get some weirdness, say if ball is “more than halfway” through, the resolution might push it out the bottom, giving same visual effect as if it had just passed through)

in a fast moving example, where ball’s single-frame velocity exceeds platform height, that’ll fail, doesn’t matter that platform is no longer a sensor NOW, because the ball has already moved beyond it, so no collision at all (let alone a response).

so you set it up so:  platform is always “there” (never a sensor), use bullet/continuous to overcome tunneling, use preCollision to disable as desired.

Thanks for the clarification, I expected that an option such as physics.setContinuous(enabled) / isBullet=true would make it real time instead of having to wait for the next frame.

Anyway, I’m giving up on isSensor, any idea of how I can make the game look faster without having to modify physics.setScale?

Thanks

endy

the thing to “get” with box2d is events are always seen by you “after” they’re seen in the simulation - box2d can’t actually predict the future and send you events in advance.  (it can make some educated guesses wrt bullet/continuous, but things still might change, and regardless, that’s internal prediction only, you won’t get events until they actually happen)  even “pre” collision events still occur “after” the potential precollision conditions have been “noticed” by simulation.

re “look faster” – first, say that over and over and over in your head, until its literal meaning sinks in.  always remembering that box2d is a simulation of the real world, and there’s what it “is” and what it “looks like”.  so, two basic approaches to altering it:  change the real-world model (what it “is”), or give up on the real world accuracy entirely and just model a fictitious/arbitrary world (what it “looks like”).

setScale is for the former - ask yourself what real-world size are those balls?  scale is set in pixels/meter, so if using default 30 an adult human male would appear about 54 pixels (1.8m) tall.  so your 40px balls are a bit more than a meter (~4’) in real-world terms.  Is that what you intend?  Or do you intend them to be “marble-sized” or “planet-sized”?  adjust scale as necessary, and correct for the effect that all forces will also be scaled accordingly.  put a bitmap of a human to scale in there, might help your brain “feel” the speed better.

or go nonsensical and decouple time to achieve “look faster”.  consider, this is essentially the default when running at 30fps (not accounting for real-world framerate irregularities):  physics.setTimeStep(1/30)

so try this to run the whole simulation 4X faster:  physics.setTimeStep(1/30*4)

in this case all forces remain as they were, but time has been altered, so apparent velocity changes, aka “looks faster”.  (that is, it’s not actually faster, a simulated second is still a simulated second, it just looks faster, because you’re doing four simulated seconds per real-world second)

of course, you can combine fake-time with an arbitrary scale to get a hybrid nonsensical world to your taste, (say 2X time with 2X scale), along with arbitrary gravity and gravityScale’s and etc to fine tune as desired.  for most games it’s all illusion anyway, so as long as it looks right then you’re ok (so long as your settings aren’t SO bizarre that box2d chokes).

Hi @endy,

What Dave says is correct: you need to react to Box2D events, not “predict” them. Even pre-collisions are not predicting what will happen, but rather, they simply give you the opportunity to handle something before the body takes the step/move that it was going to take, and that it will take immediately following the pre-collision.

Also, to clarify, sensors are not invalid or impractical in the case of one-sided platforms. You’ll notice that my demo in the tutorial actually uses both pre-collisions and normal collisions, and uses sensor toggling to detect when the bubbles should be sensors or not be sensors.

Brent

Thanks for the input guys. 

physics.setTimeStep() was the function I was looking for. Increasing the game speed with this function instead of setScale made my collision bug appear much less frequently, around once in 500 collisions instead of 50. Later I’ll try to make it reproducible.

Thanks again

endy

Honestly, I would not adjust the physics scaling. I’ve never done it so I can’t advise on that.

However, if things need speeding up you can reduce the linear and angular damping (if there is any to begin with.) You can also reduce the density of objects.

If objects are moving too fast to collide with other objects it could be that they’re going too fast and you need to use object.isBullet=true

Hi Horace,

I did not know about the damping properties. I will try them and let you know. 

edit: nevermind, I just checked the damping doc and it says default value is 0 and I was not setting anything.

They do collide, and in time, since at the time of collision the ball is still above the platform, I just understand why the ball still goes through the platform. Also as mentioned in OP, I already tried isBullet=true, it has no effect at all.

Thanks

endy

Hi @endy,

Just to confirm, are you getting a collision event when the ball hits the platform? We need to rule that out first. If you’re getting the collision event reported, then at least we know it’s not an issue with how you’re handling the collision.

Brent

Hi Brent,

Yes, a collision is detected (I get the console output giving me the height of the ball and the platform)

It looks like setting isSensor=false is lagging.

Thanks

endy
 

Hi @endy,

So if I understand your intention, when the ball is coming from one side (above or below, not sure which), you want to have it pass through the platform, but not vice-versa? Thus, you change it to a non -sensor (.isSensor=false) in that case?

For one-sided platforms, you should really explore the PRE-collision event. I posted a tutorial on this very topic awhile back, and it includes a sample project which you can explore the code for.

http://coronalabs.com/blog/2012/11/27/introducing-physics-event-contact/

Brent

Hi Brent, 

That’s right.

Ok, so the whole story is that last week I started with your tutorial and it worked pretty well. Except that all the physics seemed sluggish (I am not using any damping just to be clear) so I increased physics.setScale which gave me the very dynamic game play I wanted. Except that now, once in around 50 collisions (precollisions) the character bounces on the platform instead of going through. After a lot of testing, it seems that event.contact.isEnable = false is lagging a bit, and by the time it becomes effective, the character has already bounced back.

So I decided to go through all Corona physics doc again and noticed the isSensor property which seemed could be used for jump through platforms. I decided to build a very simple demo that I posted above with isSensor, and noticed that I was also facing some issues in a high speed context. In the demo I posted in OP, it feels like isSensor = false is lagging too.

I am new to Corona and I really like it, however I need to make sure that I can achieve proper collisions handling in a high speed context before going further (ie: buying pro version).

Also just for the sake of improving my Corona skills, I would really like to understand the issue in question 2 of my OP (why none of the options for real time detection have any impact on the collision detection).

Alternatively, if you have a way to increase game speed without changing physics.setScale(), that would be fine too.

Sorry for the wall of text I just want to make sure everything is clear.

Thanks

endy