Jump to content

P2 No collision at certain velocity


Recommended Posts


I just want to make sure there is nothing I am missing before reporting this as a bug.

I've created a small test case where a ball go through a wall although it shouldn't because there is the `collide` between the two body materials. I've tried playing with the contactMaterial options without any success. Everything is fine but as a certain velocity where it go through. For instance, if you change the x velocity value to 650, the ball will not go through.

Here is the JSFiddle example: https://jsfiddle.net/ygk5dcw4/

I've put a debugger on the "console.log('it overlaps!!!');" on the first occurrence and debugged a bit and the "runNarrowphase" method will return that there is no collision between the ball and the wall. Although, on the second occurrence, the same method returns a collision.

Please let me know if I am doing something wrong before I post this as a bug.

Thank you very much! :)

Edited by clesquir
JsFiddle url change since JsFiddle fixed their SSL breach
Link to comment
Share on other sites

I have no experience with P2 physics.

What you're describing is called "tunneling". Basically, the velocity of the thing you're colliding is high enough that the physics system is unable to test its entire path through the thing you want to collide it against. Google around for "gamedev physics tunneling" and you'll find lots of examples of how to mitigate it. 

That said, I've got to believe that you can set checks for this in P2. I'm seeing stuff for "continuous collision detection" in the P2 Body documentation on their site. That's *probably* it? But you should check.

Also: nice demo! Succinct demonstration of the bug you're trying to show.

Link to comment
Share on other sites

Thank you very much for the fast reply!

Knowing the name of the issue is a great start and as you say, there seem to have a lot of people experiencing this. Unfortunately, the Continuous Collision Detection is not implemented in the Phaser P2 physics yet so I will have to find a workaround for this or find someone who did and shared it.

I will post how I resolved this with the Phaser P2 physics as soon as I find a solution so everyone can find it.

Thanks again!

If anybody else has implemented a solution for CCD and tunneling, please do not hesitate to join the discussion!! :P

Link to comment
Share on other sites

  • 3 weeks later...

Hello all!

First, just to let you know that I am not full time on this. Nevertheless I have find a way to fix this issue for my particular case. I am giving you my findings on this here.


1) In P2 physics, there is a CCD (Continuous Collision Detection) functionality implemented but of what I understood it is flagged as experimental (https://github.com/schteppe/p2.js/releases/tag/v0.6.1). They have created a new physic called Box2d which is not free and has this implemented by default.

So I've headed towards P2 CCD to fix the issue with the two body properties ccdSpeedThreshold and ccdIterations. That worked well until I've encountered problems on which I didn't have any other solutions. The collision detection is against all objects... not only the ones configured with the body.collides method for one body.

Here is the JsFiddle example of this: https://jsfiddle.net/3ypmvwqe/ - The lowest ball collides correctly against a configured collision wall but the highest ball collides against a wall which is not configured...

This has a lot of importance in the game I am building since different objects have different collision groups.


2) So then I went back to the original problem, the collision with the ball is not detected with the collides callback but is with the this.ball.overlap(this.wall). By debugging, I found out that the problem was with the built-in polygons, and more precisely the circle. I found out some articles on the Internet going this way as well.

Here is the JsFiddle example with the ball shape replaced with a precise enough polygon at same velocity: https://jsfiddle.net/k8k1aa5g/

That is fixing more than 80% of the "passing through wall". Combined with a method to limit the velocity (found here), that pretty much fixes 99% of it!

constrainVelocity(body, maxVelocity) {
	var angle, currVelocitySqr, vx, vy;
	vx = body.velocity.x;
	vy = body.velocity.y;
	currVelocitySqr = vx * vx + vy * vy;
	if (currVelocitySqr > maxVelocity * maxVelocity) {
		angle = Math.atan2(vy, vx);
		vx = Math.cos(angle) * maxVelocity;
		vy = Math.sin(angle) * maxVelocity;
		body.velocity.x = vx;
		body.velocity.y = vy;

Hope that will help people with the same kind of problem in the future!

Link to comment
Share on other sites


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...