How does one organize sprite movement in a game?

by Paul Hsieh
When dealing with motion of objects in space in realtime under some theoretical locomotion, one ordinarily deals with giving that object a velocity and letting it proceed by its own momentum. Its is under these circumstances that I posted the following to some time ago.

  Suppose you have:

  Starting postiton: (x0,y0)
  Ending position:   (x1,y1)
  Velocity:          v
  Elapsed time:      t

  Then compute your hypontenuse *once*; i.e., when you compute the
  destination position, and velocity, also compute the hypontenuse
  between the two points.  So you can assume you also have:

  Hypotenuse:        h = sqrt( (x0-x1)*(x0-x1) + (y0-y1)*(y0-y1) );

  Then for a given elapsed time (since your sprite was at its starting
  point) you get the current position (x,y) as:

  x = x0 + ((x1-x0) * v * t) / h;
  y = y0 + ((y1-y0) * v * t) / h;

  Once (t * v) has equalled or exceeded h, you know that the sprite has
  reached or exceeded its end point.  As a simple optimization you can
  precompute (x1-x0) and (y1-y0).

  Simple physics.  For accuracy reasons its important to maintain the
  old (x0,y0) as well as the target (x1,y1) (or (x1-x0,y1-y0) which
  would be equivalent), the variables v,t and h should be floating
  point values and the equations given above should be computed with
  the give order of operations.  This will allow you to maintain
  x,y,x0,y0,x1,y1 as integers if you wish.

  If you use floating point variables only, you can relax the order of
  operation requirements and precompute (v/h) beforehand.  This would
  also allow you to drop the values of (x0,y0) and use an incremental
  approach (using delta t, rather than t since starting) but then the
  end detection strategy has to change.

  The advantage of the floating point method is that you can avoid an
  extra divide (which is nasty) and you have the opportunity to use the
  FPU for calculations.  The disadvantage is that most graphics
  libraries prefer to receive integer coordinates, hence a conversion
  is required.

Changing motion should be acheived by changing "v" and/or (x1,y1) in an AI, or player update phase of your application. However if your goal is to take gravity into account then you might proceed as follows:

  Suppose you have:

  Starting height:            z0
  Starting Velocity:          v0
  Acceleration constant:      a
  Absolute terminal velocity: vt
  Elapsed time:               t

  Here everything is considered in floating point notation.  Then the
  new height and velocity would be computed as:

  z = (a/2)*(t * t) + (v0 * t) + z0
  v = v0 + (a * t)

  The velocity "v" is ordinarily clamped by the "terminal velocity" 
  beyond which the velocity can never go above or below.  Once the 
  velocity reaches "terminal velocity" (i.e., abs(v0)>=vt) the height 
  should be updated linearly as follows:

  z = (v0 * t) + z0

  If the update causes the velocity to go from non-terminal to 
  terminal (abs(v0 + a * t)>=vt>abs(vo)) then for complete accuracy you 
  should compute the update in two parts by first calculating the two 
  time intervals t0 and (t-t0) according to:

  t0 = (vt*sgn(v0 + (a * t)) - v0)/a

  Then iterate the two updating formulae above in order according to 
  z0 <- z and v0 <- v first with t <- t0 then with t <- (t-t0).
  sgn is a function returning 1, 0, -1 depending on the sign of the
  argument, such that x == abs(x)*sgn(x).

  Note that it makes little sense to perform these computations in 
  more than one axis at a time.  You should orient your Z-axis to 
  point towards the center of gravity.  If this is not possible then 
  you end up with an acceleration and velocity vector, rather than
  constants above.  

  If you have more than one gravitational force, then you have to use 
  an "n-body" solutions to the problem.  There is a well known 
  approximation method that uses differences on the taylor expansion 
  of the motion path vectors which acheives accuracy on the order of
  the fourth derivative multiplied by a smallish factor.

This page hosted by

Copyright © 1996, Paul Hsieh All Rights Reserved.