Animating an image using Path and PathMeasure – Android

Animating an image along a predefined path (be it a line or a curve) is a common situation that game developers face. Instead of doing it the usual way (Finding the equation of the path, substituting x and finding y values and then using the co-ordinates [x,y] for the animation), we can do this in a more simpler way by making use of Path and PathMeasure.

If you already have a game loop running with its update and render cycles, the following code can easily be implemented. If you’re new to game loops, Obviam.net explains the concept behind game loops in a very concise manner.

Suppose, I want to move an image in a straight line from (0,0) to, say, (100, 100).

Following is a code snippet that shows you how to do it:

Declare the variables that we’d be using:

Path path;
PathMeasure measure;
float[] pos, tan;
float speed, distance;

Initialize your Path object and other variables that we’d be using later on. You could do this on your surfaceCreated() callback if you are using a SurfaceView.

// Init the Path.
 path=new Path();

// Set the starting position of the path to (0,0).
 path.moveTo(0,0); 

// Add a line to the Path, starting from (0,0), ending at (100, 100).
 path.lineTo(100,100); 

// Create a PathMeasure object, passing in the Path object
 // we created and a boolean that specifies if the Path should
 // be forced to a closed path.
 measure = new PathMeasure(path, false);

// Here, we're dividing the whole length of the path by 30.
 speed = measure.getLength() / 30;


pos=new float[2];
 tan=new float[2];

The concept behind the moving of the image is simple: Staring at (0,0), in every update cycle, we find a point along the defined path, traversing a little each time.
Now inside the update() method of our game loop, we’d be doing the following:

 public void update()
 {
 while(distance < measure.getLength())
 {

    // getPosTan pins the distance along the Path and
 // computes the position and the tangent.
 measure.getPosTan(distance, pos, tan);

     distance += speed;   // Traversal
 }
 }


Now to render,

 public void render(Canvas canvas)
 {

    //Draw the bitmap on the canvas, passing in the
 //Bitmap object, the x and y co-ordinate and a
 // Paint object.
 canvas.render(bmpImage, pos[0], pos[1], null);
 }
 

Here the speed directly determines the speed of the animation. Playing with that value, you can arrive at your desired speed.

Just like a line, you can also use curves, Bezier curves, arcs, etc., and a combination of these as well.

Hope this helps!