Jump to content

Help with P2JS and Pinball Physics?


Recommended Posts

Hi all


I'm trying to make a toy game that's a pinball game.


For this I needed good Physics so I opted for P2JS


Have a look at this current version:



Here is the source easier to read (you can see I've been at this for a while! @#$%$)



I'm having big issues with the physics system though...


- all materials feel gooey. Ball seem to soften into all other parts... that's not great.

- when moving the flippers, the ball quite often falls through... Is it because the refresh rate is too slow? is there a function to call to force a refresh of the physics system? Or does the physics system does not support fast moving items?

- no matter what I tweak, the bounciness feels odd. Center of a surface seems to be a lot bouncier than the edges!

- I couldn't figure out how to change the pivot (center of rotation) of the P2JS body... I opted with using larger PNG and shifting the position of the sprite inside, giving me a large P2JS body.


Are any of you familiar enough with P2JS? Documentation is... sparse to say the least.


Can you help with any of the items above?



Link to comment
Share on other sites

Hi keyle,

look at this pinball example.



This is a really basic example AND it's based on a very early integration of p2 in phaser- so you can't simply copy & paste the code (well the coffee script would be your first problem). But you can see a better collision behavior between the ball and the flippers. The trick ? Nothing. Use the default contact material (that is: do net specify any). Really. Touch the contact material again when you have a better understanding of the whole physics environment. Focus on other problems you can fix easier.


The problems in your current version:

+ There is no point of applying restitution to a ball - flipper collision. Leave it at the default.

+ Remove the surfaceVelocity. This is so wrong her ;)

+ Do not set the friction to zero unless your flippers are made of ice.

Each of those parameters create a really awkward feeling in your current example. And you use all of them. Just remove the whole contact material definition.


And never ever set the mass of the flippers to 1000. The unit is kg. You really do not want a flipper with 1000kg. I guess this is one of your approaches to fix your bounciness problem. Remove it. The mass is calculated based on the shape. It's right in most of the cases. It should be right in your case (I have not a single custom mass in my current pinball implementation and I feels a lot more better than the prototype mentioned above !)


And another hint:

Use a motor with a revolute constraint to rotate your flippers! Your current solution depends on increasing and decreasing the value of the angle. You do this in the update step outside of the physics engine. I believe that's the reason for your fall throughs. your rotation is a lot more faster than the physics engine will calculate the collision. For p2 you set the angle fro ma very low to a very high value without touching the middle values (where the collision would take place).


There is indeed a parameter to increase the 'resolution'. It's called iterations inside the class GSSolver (which is one type of a solver, default one in phaser's p2 integration). The default is 10. So there a 10 steps within a single time step to solve collisions. You can't fix your error by increasing this value as the angle updates are not managed by the physics engine- to do so: use motors ;)


Use a polygon and not a rectangle for your flippers. So you will get a perfect match of your sprite with your physics body.


Here some functions you may use in your code. Have fun!

// pivotCenter: pivot around the flipper arm
// ground: the body to attach the flippers to, I simply created a 'ground body'

ground = new p2.Body();
offsets = [0,0]
revoluteConstraint = game.physics.p2.createRevoluteConstraint(flipperLeft, [ pivotCenter.x, pivotCenter.y ], ground, offsets);

//set upper and lower limits for angle in the constraint
revoluteConstraint.upperLimit = Phaser.Math.degToRad( 0)
revoluteConstraint.lowerLimit = Phaser.Math.degToRad( 35)

revoluteConstraint.setMotorSpeed(12) //set some speed of the motor, when enabled

//when you want to rotate a flipper use the motor.

//disable the motor to flip them back (by gravity)

//or let the motor enabled all the time and modify the upper/lower limits
revoluteConstraint.upperLimit = Phaser.Math.degToRad( 35)
revoluteConstraint.lowerLimit = Phaser.Math.degToRad( 35)

revoluteConstraint.upperLimit = Phaser.Math.degToRad( 35)
revoluteConstraint.lowerLimit = Phaser.Math.degToRad( 35)

Link to comment
Share on other sites


  • Recently Browsing   0 members

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