5
\$\begingroup\$

I am trying to create a spinning wheel which slows down after a specific time. I managed to simulate the slowdown of the wheel but I need also to put a needle which go up and down with an angle of 45°.

Here my wheel with the needle :

enter image description here

My wheel turn in clockwise and the needle (object in red in the above scheme) rotate in counter clockwise.

enter image description here

Once done the needle back to his original position slower than the previous movement.

enter image description here

The code i wrote :

// Once 3 seconds are passed, the speed rotation start to decrease
If RealMillisecs() -_fRotateTime > 3000 Then
    If _fSpeedRotation > 0 Then
        _fSpeedRotation = _fSpeedRotation - 0.001
    Else
        _fSpeedRotation = 0
    EndIf           
EndIf

_fWheelRotation -= _fSpeedRotation * dt.frametime

// If the needle is not going back to its orginal position then is going up
If not _bAnimBackNeedle Then
    _fNeedleRotation = _fWheelRotation Mod 45 * -1

   /* If its previous rotation greater than actual position 
    it's mean that the needle has reach its max angle (45)*/
    If _fNeedleRotation < _fPreviousNeedleRotation Then
        _bAnimBackNeedle = True // The going back animation to true
    EndIf

    _fPreviousNeedleRotation = _fNeedleRotation
EndIf

// If the going back animation is set to true or the wheel has stopped to turn
// get the needle back to its position at constant speed    
If _bAnimBackNeedle Or _fSpeedRotation = 0 Then
    _fNeedleRotation -= 0.5 * dt.frametime
    If _fNeedleRotation <= 0 Then
        _bAnimBackNeedle = False
    EndIf
EndIf

My code doesn't make what i hope.

The needle doesn't come back to its original position when the wheel is stopped.

How can I managed the code to have the wheel and the needle with a good behaviour?

\$\endgroup\$
12
\$\begingroup\$

How about letting box2d do the work for you? It wasn't too difficult for me to setup everything in RUBE:

enter image description here

There are two major parts: the wheel and the needle.

Wheel

wheel

  1. First there is a base. In this case the base is a static body with a square fixture.
  2. The wheel is attached to the base via a revolute joint. This joint allows the wheel to spin freely about the center.
  3. The wheel consists of 33 circle fixtures: 1 big wheel and 32 pegs. I created the pegs using a simple Rubescript. The pegs and wheel are on different bitplanes, allowing the needle to collide only with the pegs and not the wheel. One other ajustment is that the boolean isBullet needs to be true; the reason for this is that the pegs can move very quickly when the wheel is spinning fast and sometimes the peg-needle collision will be missed by box2d. If the isBullet flag is set, box2d resolves those cases correctly.

Needle

Needle

  1. The needle is a body with a single fixture in the shape of a kite. I have increased the friction a little on the needle fixture and peg fixtures. This way when the needle rubs against the pegs it will eventually slow the wheel down. We also need to set the bitplane and bitmask of the needle so it only collides with the pegs.
  2. The needle can rotate about the revolute joint. The second body for the revolute joint is the static body from before.
  3. Two opposing distance joints act as springs to try and keep the needle in place. The damping parameter on the distance joints also helps dissipate the wheel's energy.

Result

Wheel of Fortune GIF

You get a lot of nice realisms when you go with a physics-based solution. Most notably, you can let the player actually spin the wheel with a swipe of their finger or a click+drag of their mouse. Also, it's easy to do things like add more needles for more players if you want to.

I know there is a lot of stuff here specific to box2d which you might not be familiar with but it is well worth learning IMO. The spinning wheel is an excellent way for you to get started.

\$\endgroup\$
  • \$\begingroup\$ Mile. Thanks for this detailed answer. It' works really great with box 2D, i thought that use box 2D would be too difficult to understand and implement with my code. But with RUBE it's seems more easly. \$\endgroup\$ – Moerin Mar 27 '14 at 19:57
0
\$\begingroup\$

As a side-note, your use of EndIf makes me think you're trying to do this in PHP - which makes no sense whatsoever, but whatever. It would help if you could clarify what language you're working with.

But concerning the mathematics alone...

The two events you need to catch are when the edge of the space contacts the needle and when the edge breaks contact with the needle.

if( (fWheelRotation + 7) % 45 < 6 )
{
    fNeedleRotation = ((((367 - fWheelRotation) % 45)^2) * 1.8);
} else {
    if( fNeedleRotation < 0 )
    {
        fNeedleRotation = 0;
    } 
    else if( fNeedleRotation < 46 )
    {
        fNeedleRotation -= 10;  // Adjust this value to control return speed
                                // Be sure to allow a small overshoot
    }
}

Due to how close to the threshold you're operating, the offset offers a buffer. Without the buffer, a fast-spinning wheel could bypass the (much smaller) trigger zone(s) without the needle responding.

I could offer a slightly more elegant solution if you included what language you're using.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.