0
\$\begingroup\$

I have a Box2D project and I want to tween an kinematic body from position A, to position B. The tween function, got it from this blog:

function easeInOut(t , b, c, d ){
    if ( ( t /= d / 2 ) < 1){
        return c/2 * t * t * t * t + b;
    }
    return -c/2 * ( (t -= 2 ) * t * t * t - 2 ) + b;
}

where t is the current value, b the start, c the end and d the total amount of frames (in my case). I am using the method introduced by this lesson of todd's b2d tutorials to move the body by setting its linear Velocity

so here is relevant update code of the sprite:

if( moveData.current == moveData.total ){
        this._body.SetLinearVelocity( new b2Vec2() );
        return;
    }

    var t = easeNone( moveData.current, 0, 1, moveData.total );

    var step = moveData.length / moveData.total * t;

    var dir = moveData.direction.Copy();

    //this is the line that I think might be corrected
    dir.Multiply( t * moveData.length * fps /moveData.total ) ;

    var bodyPosition = this._body.GetWorldCenter();

    var idealPosition = bodyPosition.Copy();
        idealPosition.Add( dir );

    idealPosition.Subtract( bodyPosition.Copy() );

    moveData.current++;


    this._body.SetLinearVelocity( idealPosition );

moveData is an Object that holds the global values of the tween, namely:

  • current frame (int),
  • total frames (int),
  • the length of the total distance to travel (float)
  • the direction vector (targetposition - bodyposition) (b2Vec2) and
  • the start of the tween (bodyposition) (b2Vec2)

Goal is to tween the body based on a fixed amount of frames: in moveData.total frames.

The value of t is always between 0 and 1 and the only thing that is not working correctly is the resulting distance the body travels.

I need to calculate the multiplier for the direction vector. What am I missing to make it work??

Greetings philipp

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

I have got it working now! I just missed one vector difference and one multiplication.

here is the code:

function moveFocused( center, bbox ){
    var moveData;
    if( ! this._animationData.hasOwnProperty( 'moveFocus' ) ){
        this._body.SetLinearVelocity( new b2Vec2() );
        setBodyType.call( this, b2Body.b2_kinematicBody );
        var m = this._animationData[ 'moveFocus' ] = {};
        m.start = this._body.GetWorldCenter().Copy();
        m.direction = new b2Vec2( center.x - m.start.x, center.y - m.start.y );
        m.current = 1;
        m.total = 10;
    }

    moveData = this._animationData.moveFocus;

    if( moveData.current == moveData.total + 1 ){
        this._body.SetLinearVelocity( new b2Vec2() );
        return;
    }

    var t = easeInOut( moveData.current, 0, 1, moveData.total );

    var sEnd = moveData.direction.Copy();
        sEnd.Multiply( t );
        sEnd.Add( moveData.start.Copy() );

    var sStart = this._body.GetWorldCenter();

        sEnd.Subtract( sStart );
        sEnd.Multiply( fps );

    moveData.current++;


    this._body.SetLinearVelocity( sEnd );
}

the fun is the line where t get calculated, because there the tween functions come into play and it is possible exchange them against each other, what makes it very easy to test different easing.

Btw: It is working for dynamic bodies too.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for coming back with your solution :). Too many people just hit and run. \$\endgroup\$
    – Roy T.
    Sep 13, 2012 at 13:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .