1
\$\begingroup\$

I have a sprite that I want to rotate smoothly and face the opposite direction:

This is my render function:

public void render() {
    // Game Loop

    Gdx.gl.glClearColor(0.7f, 0.7f, 0.2f, 1);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    spriteBatch.begin();        

    if(bug.getX() >= (int)(Gdx.graphics.getWidth() - 100) && bug.getY() >= (int)(Gdx.graphics.getHeight() - 100)){
        bug.rotate(rotDeg);
        turn = !turn;
    }
    else if(bug.getX() <= 0 && bug.getY() <= 0){
        bug.rotate(rotDeg);
        turn = !turn;
    }

    if(!turn){          
        bug.translate(v.x * Gdx.graphics.getDeltaTime(), v.y * Gdx.graphics.getDeltaTime());
    }
    else{
        bug.translate(-(v.x * Gdx.graphics.getDeltaTime()), -(v.y * Gdx.graphics.getDeltaTime()));
    }


    bug.draw(spriteBatch);
    spriteBatch.end();
}

What my code does is that when it reaches the destination (top right corner, or bottom left corner), it immediatly turns facing the opposite direction. How would I make this turn smoothly?

\$\endgroup\$
1
\$\begingroup\$

You may want to look into tweening, which is what's used to smooth out animations using various smoothing functions. If you don't wish to implement anything yourself, you may want to look into: http://code.google.com/p/java-universal-tween-engine/.

\$\endgroup\$
0
\$\begingroup\$

Given an angle you wish to rotate to angleTo, and the current angle angle, you can apply an easing function to angle as follows (assuming all angles are in degrees):

// see http://stackoverflow.com/a/7869457/1446919
double angleDifference = (angleTo - angle + 180) % (360) - 180;

double ease = 0.1;
angle += angleDifference * ease;

// Ensures angle reaches angleTo when the difference is very small
if (Math.abs(angleDifference) < 1) {
    angle = angleTo;
}

So in your implementation, you can check when the bug is out of bounds, set angleTo and the turn flag to true until angle reaches angleTo, then unset the turn flag:

if (!turn) {
    if((bug.getX() >= (int)(Gdx.graphics.getWidth() - 100) && bug.getY() >= (int)(Gdx.graphics.getHeight() - 100))
    || (bug.getX() <= 0 && bug.getY() <= 0)) {
        turn = true;
        angleTo = bug.getAngle() + 180;
    }
} else {
    double angleDifference = (angleTo - angle + 180) % (360) - 180;
    bug.rotate(angleDifference * ease);
    if (Math.abs(angleDifference) < 1) {
        turn = false;
    }
}
\$\endgroup\$
0
\$\begingroup\$

if you want to rotate slowly to a given angle, you need to calculate the delta angle, from the current angle to the destination angle. can be done easly with like this-

Vector2 dest = new Vector2(0,1); // angle to reach
Vector2 curr = new Vector2(0,-1); // whatever the current Bug angle is

float deltaAngle = dest.angle(curr); 

//the `angle` method will return a number between -180 and 180.

float speed = 180; // degrees passed per second. play with it to reach the rotation speed you want

speed *= deltaTime; // parameter from Render method for consistant speed

// if the distance is too small just set the position
if (dest.epsilonEquals(curr,speed * MathUtils.degreesToRadians))
{
    // reached the destination angle. do whatever
    curr = dest;
}
else
{
    if(deltaAngle > 0)
    {
        speed *= -1; // rotate the other way around if its shorter that way
    }

    curr.add(speed).nor();
}
\$\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.