Tokeijikaku
Tokeijikaku

Reputation: 1

Non-fixed ease-in-out behavior for 2D entities

I'm creating a class for sprites that support a variety of behaviors that move the sprite towards a target point, and I'm testing them using a mouse follower.

I want it to have support for an ease-in-out kind of behavior, accelerating it and then decelerating it as it approaches the target point.

This is not to be a fixed animation with a fixed duration and other fixed circumstances, rather it is to be, well, a behavior, taking the form of a function that is called once every timestep, with no reference to were the move started or how long it will take or anything like that - just its current target position and some modifiers to the behavior itself. To illustrate the concept, here are two other functions that I've created for the class, beginning with the simplest:

void ElasticSprite::easeOutMove(int targetX, int targetY, unsigned friction)
{
    _xPosition += (targetX-_xPosition)/friction;
    _yPosition += (targetY-_yPosition)/friction;
}

(I've altered the code so that it's library-independent, the real deal uses SFML stuff)

This function moves the sprite in a simple ease-out fashion towards the target point.

My second example:

void ElasticSprite::rubberMove(int targetX, int targetY, unsigned friction, unsigned elasticity)
{
    _xSpeed += (targetX-_xPosition)/friction-_xSpeed/elasticity;
    _ySpeed += (targetY-_yPosition)/friction-_ySpeed/elasticity;

    _xPosition += _xSpeed;
    _yPosition += _ySpeed;
}

Exactly what it says on the tin, this function makes the sprite behave in a rubbery fashion, speeding past the target point and then back and forth across it until it slows down to a halt. If you start moving the target point around (the mouse, in my case) the behavior isn't reset, it instead starts going after the new target point.

I want an ease-in-ease-out function, and by extension a version of rubberMove that accelerates by the same rule, but I'm completely stumped as to how it's supposed to work. I want the acceleration rate of this function to depend on the distance between the current position of the sprite and its target position (targetX-_xPosition and targetY-_yPosition, multiplied by an acceleration modifier), which means that if the sprite starts out completely still at one position, it should take it the same amount of time to reach any other position, it's peak speed being at the mid-point in both time and distance.

Does anyone have any suggestions as to how this behavior could be implemented?

Upvotes: 0

Views: 215

Answers (1)

Fennekin
Fennekin

Reputation: 216

"If you start moving the target point around (the mouse, in my case) the behavior isn't reset, it instead starts going after the new target point."

1)you need to have a timer function so that it accepts the target position at particular time and goes to the point,instead of following mouse everywhere. 2)you can use the concept of inertia for gradual acceleration.

void ElasticSprite::rubberMove(int targetX, int targetY, unsigned friction, unsigned   elasticity)
{
//the timer event will set the initial x speed and y speed.


_xSpeed *= 1-friction // where friction < 1; 
_ySpeed *= 1-friction // where friction < 1;

_xPosition += _xSpeed;
_yPosition += _ySpeed;
}

  do this until you get to desired point.

Upvotes: 0

Related Questions