2d Physics Rotation

I’ve recently started playing around with the 2d physics integration, and I’ve encountered something I can’t quite wrap my head around.
The project is a prize wheel, like what many games use for random prize mini games or daily bonuses. Despite starting the wheel at the same angle every time I spin it, the end angle is always different with a huge margin of error. It stops anywhere within a 190 degree area centered on the start point, and I need to reduce this down to a 30 degree area.

At a guess, the p2.js physics and ammo.js are not deterministic. ie You cannot reproduce the same result every time.

You might be able to fudge/modify p2.js to not use a varied timestep and use a fixed timestep instead which might help. This may visually look odd on some machines though if the framerate varies.

Or you can just not physics at all and write your own deterministic code for rotating the wheel.

I’ve been trying that as well using tweens, but I have a somewhat similar issue with it. Because the tweens try and find the shortest route from point a to point b, the rotation sometimes reverses when the tween to the winning angle begins.
(More info on that here)

This is also a small part of a larger project, and the other people I’m working with suggested trying the 2d physics over 3d and tweening. I’m also the guinea pig to see if Play Canvas would be a suitable engine for future projects.

Don’t use the entity tweens. You can just have an variable for the angle and lerp between one value to another with a curve.

As a really simple example:


Look for the entity ‘Wheel - no physics’.

Okay, I think I get what your doing there. Just to clarify, spin duration is how long it will take to rotate to the target angle correct?

EDIT: Played around with it and this works like a charm! Thank you very much!

Little question about the script idea @yaustar provided. When I start the spin, the speed up is instantaneous and I’m wondering if there’s a way to make the speed up gradual instead using this method.
Here’s my script for reference: Spin.js

The tween I used was easeOutQuint which looks like this as a graph:


Which you can see has high initial acceleration and then a slow deceleration.

You can use other tweens as well. In this case, a inOut variant could work:


If that doesn’t give you the control you want, you can create your own curve using the curve attribute which allows you to do the curve you want: https://developer.playcanvas.com/en/api/pc.Curve.html

Project example: https://developer.playcanvas.com/en/tutorials/animate-entities-with-curves/

Ah ok, do I need to change anything here aside from changing it to easeInOut? function easeInOutQuint(t) { return 1+(--t)*t*t*t*t; }

No but after using it myself, I don’t think it gives the effect you want as the middle part (where it is spinning the fastest) is quite short in duration.

I think using the curve attribute is your best bet.

I was noticing that, there didn’t seem to be much of a wind up, it still quickly accelerated and then went into the nice smooth slow down.

It shouldn’t accelerate quicker than the deceleration. This is what mine looks like:


Which is exactly how I want mine to look, but as I said it still gets that instant acceleration right at the start and the smooth slow down at the end. https://launch.playcanvas.com/593817?debug=true

I need to correct myself here. It seems like you’ve just changed the function name and not the actual code :sweat_smile: I assumed you also changed the code.

You need to change the actual code :stuck_out_tongue: as well

Here is the code of the tweens/eases I use: https://gist.github.com/gre/1650294
And the related graphs: http://easings.net/

I found this library of easing functions in a comment on the one you linked. Any idea how to get the easeInOutBack one to work? I’ve tried it two different ways and nothing.

Can you show how you have tried it?

I tried including the entire easing.js and using in the same way you would the tween library, but that didn’t work, then I tried just using the function for inOutBack from it.
I left a few things out the first time I tried just using the function, which is why that didn’t work, and the second time i just incorporated it as:

function easeInOutBack(t, m) 
    m = 1.70158;
    var sT = t*2;
    var s2 = sT - 2;
    var s = m*1.525;
    if(sT < 1)
        return 0.5*sT*sT*(((s+1)*sT)-s);
    return 0.5*(s2*s2*((s+1)*s2+s)+2);

When I clicked the button to make it spin, the model just disappeared.

The function you have wrote above had a default value for m (https://github.com/AndrewRayCode/easing-utils/blob/master/src/easing.js#L177) which is probably why it ‘disappeared’.

The code I was looking at for easeInOutQuint is here: https://github.com/AndrewRayCode/easing-utils/blob/master/src/easing.js#L83

Which would be:

function easeInOutQuint( t ) {
    const t1 = t - 1;
    return t < 0.5 ? 16 * t * t * t * t * t : 1 + 16 * t1 * t1 * t1 * t1 * t1;

The exact one I used was:

function easeInOutQuint(t) { return t<0.5 ? 16*t*t*t*t*t : 1+16*(--t)*t*t*t*t; }

I tried:

function easeInBack(t) 
    m = 1.70158;
    return t*t*((m+1)*t-m); 

ans it sort of worked, it sits still for a while, then spins, then sits again. The backIn from the tween library was what I was leaning toward using as it gave the initial spin the look of someone rotating the wheel in the opposite direction before putting force in the direction they want to spin it.