There are many ways to move objects in Corona SDK. If you want to move an object from point A to B, the simplest approach is to use But what if you need to move it along a path with multiple segments, like moving a knight on a chess board in its unique “L” pattern? This tutorial outlines how to achieve sequential movement via a series of queued transitions.

Initial Setup

The basis of this process is a table of x and y coordinate pairs to move the object along, in sequence. In its most simple format, the table may look like this:

This just declares a series of movement points, starting at index 1 and progressing across as many points as you wish. By default, these points equate to specific coordinates on the screen, not points relative to the object’s starting position, but we’ll include a setting to let you choose which option is most suitable to your application.

Customizing the Path Parameters

In addition to the basic x and y coordinate setup, we’ll allow two additional parameters for each “segment” in the path: time and easingMethod. For example, we may expand our table like this:

If a custom time parameter is specified, it will override any other time settings, and the object will move to that point over that exact duration. Similarly, if easingMethod is defined and set to one of Corona’s easing methods, the object will move to that point using that easing method, not the default linear interpolation.

Distance Function

For calculating the distance between two points, we’ll need to include a quick function. The purpose of this will be explained later, but let’s add it now:

Create the Object(s)

Obviously, we’ll need one or more objects to move along the path we created. Let’s create two basic circles now:

The setPath() Function

Now that we’ve done the basic setup, let’s explore the function which will queue up all of the transitions for an object. Let’s call the function setPath() and provide it with three arguments: the object to move, the path to move along, and a table of params which we can use to customize the movement.

In the first several lines of the function, we set some local variables, most of which are used to check if various parameters are passed in via the params table. Each of these parameters will be explained as we step through the tutorial.


This gives us the option to use delta position via a boolean value — useDelta — passed in via the params table. If set to true, the object’s path will be relative to its starting position. If set to false, or omitted, the path points will equate to explicit screen coordinates instead.

Whether to use params.useDelta = true depends on the scenario. For moving a knight on a chess board, delta would be the logical choice, since the knight may reside on any square of the board and we’d need to move it in its “L” pattern from the current square to another valid square.

If useDelta is passed in the params table, let’s set deltaX and deltaY to the object’s starting position, instead of their default of 0. When the transitions are set up, this will be used to offset each point along the path by the object’s starting position. It will also be used to refactor the constant rate of movement, discussed in a moment.

Constant Rate of Movement

Another option we’ll add is the ability to set a “constant rate of movement.” For example, we may wish to move the object at a steady, constant rate across the entire path, even if the distance between the starting point and the 2nd point is 100 pixels but the distance between the 2nd and 3rd point is 280 pixels. To accomplish this, we just need to calculate a speed factor based on a “time” value passed in via params.constantTime.

The value that should be passed to params.constantTime is simply an integer “time” value, and speedFactor is calculated by the distance between the starting point and the 2nd point. In other words, if we use a value of 1200, the object will move from the starting point to the 2nd point in 1200 milliseconds, and the speed established along that segment will be applied to all other segments in the path, no matter their distance apart.

Default Easing Method

If we wish to use a non-linear easing method for all segments in the path, we can tell the module to use any of the easing methods. For example, to use a quadratic-in-out method, we can pass easingMethod = easing.inOutQuad in the params table. This easing method will be applied to all transitions along the path except those with a specific easingMethod setting in the path table.

Transition Tagging

One of the features in the Transition 2.0 library is the ability to tag (name) any number of transitions and then cancel, pause, or resume all transitions sharing the same tag. Since we’ll be building paths that consist of multiple related transitions, tagging is essential if you want to pause or resume the path movement as it progresses from point to point. To tag all of the transitions that will collectively make up the path, just pass the tag parameter (string value) in the params table.

Looping Through the Points

Now, let’s loop through our points and set up the queue of transitions. For simplicity, we’ll declare all of them initially and apply a delay parameter on each, so each transition starts when the previous one is finished.

First, we’ll start our loop and immediately set a default segmentTime of 500 milliseconds. Then, we’ll check if params.constantTime has been supplied and, if so, we’ll overwrite segmentTime with a refactored time — specifically, the distance between the points multiplied by the speedFactor that we calculated above:

As mentioned above, we can optionally set a custom time on any specific segment in the path. If supplied, this value will override both the default of 500 milliseconds and the “constant rate” value, if it’s being used. Let’s check if a custom time has been specified for this segment:

In addition, let’s check if a custom easingMethod parameter has been set on this specific path segment. If declared, this will override the optional default easing method applied to the path as a whole.

And finally, the heart of the entire process — creating each transition for the path:

Notice that the parameters table for each actual transition is populated based on the values we gathered or calculated in the lines above. Also, note line #66 — here, we add to the total delay value for each new transition in sequence, thus making each transition begin when the previous one has completed.

Setting an Object in Motion

Let’s start our circles in motion across the path! At the most basic level, the setPath() function may be called like this:

However, this doesn’t include any options like useDelta or constantTime, so let’s expand on it:

And that’s it — the circles will both follow the same path, movePath, and the path will be offset by each object’s starting position because we used the delta setting. The rate of movement across each segment will be constant, and an in-out quadratic easing will be applied to all segments.

Pausing, Resuming, Canceling

Because we tagged every transition in the sequence with the "moveObject" tag, pausing, resuming, or canceling is simple — just pass the tag name to one of the transition control APIs:

In Summary

Hopefully this tutorial gets you started on path-based movement in Corona. Note that the functional format allows you to create and re-use several unique path “patterns” and apply them to various objects by simply passing the appropriate path table to the setPath() function, along with the object and the optional parameters. In this manner, you could, for example, create several different movement paths for pieces in a board game and re-use those paths as needed depending on the player’s move.

To experiment with path-based movement, please download the project and provide your feedback below.

Originally from: 

Tutorial: Moving Objects Along a Path