3
\$\begingroup\$

I have an object that orbits the player's sprite with code that looks like this:

x = player.x + sin(_float) * _radius;
y = player.y + cos(_float) * _radius;
_float += 0.01;

An event can trigger the object to fly away from the player to chase a target. After it hits the target, I would like the object to glide back toward the player and smoothly return to an orbiting path around the player.

Everything I've tried thus far just ends up making it snap to a position abruptly or completely fly away, never to return again.

EDIT: I ended up with a solution that sets the objects velocity to the sin/cos orbit instead of directly setting the x and y coordinates. Thanks for the ideas!

\$\endgroup\$
3
\$\begingroup\$

Let's take a look at the problem from a distance. We have some requirements for this object:

  • At any time the object can be in one of a number of distinct states.
  • The current state can change at any time.
  • For each state we can determine a target position at any time. This is where we would like the object to go ASAP when in this state.
  • The object should move smoothly at all times. This may mean its speed is capped at some limit, or the magnitude of its acceleration is capped at some limit, or some other definition of smoothness.

Here are two basic strategies we could take:

Continous Simulation

We write an function that takes the object's current position, the current target position, and the elapsed time since the simulation was last updated, and returns the object's new position. Some simple implementations:

  • An infinite-impulse-response low-pass filter. The object moves a fixed fraction of the distance to the target every time it is updated. This only works well if the simulation timestep is fixed, of course, and you'll probably need to manually limit the object's top speed.
  • Use a physics simulation. Apply a force in the direction of the target position and a damping force counter to the current velocity (i.e. friction) to prevent overshoot and oscillation. Calculate the resulting acceleration based on the net force and mass of the object, and integrate it to get the change in velocity. Then integrate the new velocity to get the new position. Use your physics engine if you have one. If the object is a missile or some other entity which maneuvers using thrust, this will probably give the most realistic result.

More complicated implementations might use the current/target velocity as well.

Transition Smoothing

When the current state changes, we keep track of the previous state and the time when the state change occurred. We write a function that takes the current target positions for the current and previous states, and the elapsed time since the previous state transition, and returns the object's new position. We may also want to use other information, like the object's current position/velocity or what specific states anchor the transition (not just the calculated target position), and we may want to return more information, like whether or not the transition is complete. This strategy requires a few more assumptions about the problem:

  • The target positions for each state of the object satisfy our requirements for smooth movement
  • After changing to a new state, the object's state won't change again until the transition is complete.

The smoothing function would typically just interpolate between the previous and current target positions over a fixed timespan, using your favorite interpolation method, but you could come up with a more exotic implementation as well.

\$\endgroup\$
  • \$\begingroup\$ I'm blown away by the thoroughness of your response! If it makes it easier, I have a velocity system in place. I have the ability to smooth the movement velocity from the orbiting object to the player directly with velocity.x = (player.x-x) * _accelerationSpeed I'm thinking a continuous simulation could work, something as simple as updating the motion continuously with separate variables and then guiding the object to them after it wants to return. \$\endgroup\$ – dinorider Jan 1 '18 at 1:58

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.