Circular Motion in AS3: Make One Moving Object Orbit Another

Tutorial Details
• Difficulty: Beginner
• Platform: Flash (Flash Player 10.1)
• Language: AS3
• Software Used: Flash Professional CS3
• Estimated Completion Time: 10 minutes
This entry is part 10 of 13 in the You Do The Math Session
« PreviousNext »

Having one object orbit another is a movement mechanic that’s been used since the early gaming era, and it remains handy to this very day! In this Quick Tip we will explore the mathematical function for orbiting, see how to modify it, and look at practical uses in actual game design.

Final Result Preview

Here’s what we will be working towards:

Step 1: The Orbiting Equation

To create an orbit we must define the following:

• Origin – The object or position that the orbit centers on.
• Orbiter – The object that orbits the origin.
• Angle – The current angle of the orbiter.
• Speed – The number of pixels our object orbits per frame.
• Radius – The orbiter’s distance from the origin.

It is also helpful to note that Flash’s coordinate system is like a regular cartesian plane, except that the y-axis is flipped, so the value increases as we move downwards. The top-left corner of the stage has coordinates (0,0)

In this image, 0, 90, 180, and 270 refer to angles, measured in degrees.

Another thing that we need to understand is how to convert degrees to radians, which can easily be accomplished using the following formula:

Radians = Degrees * (PI / 180)

Here’s the actual orbiting function: it requires two lines, one to position the orbiter on the x-axis and the other to position it on the y-axis:

(In a normal Cartesian plane, sin is used for the x-coord and cos is used for the y-coord, but since our angles are increasing clockwise – due to the reversed y-axis – their places are swapped.)

Step 2: Writing the Equation in Code

We can now turn the logic into actual code that we can use. First, declare all of the variables:

public var orbiter:Orbiter = new Orbiter(); // The MovieClip That Orbits
public var origin:Origin = new Origin(); // The MovieClip That Is Orbited
public var angle:Number = 0; // The Initial Angle Orbiting Starts From
public var speed:Number = 3; // Number Of Pixels Orbited Per Frame
public var radius:Number = 75; // Orbiting Distance From Origin


Next rewrite the equation for use in AS3 and put it into an ENTER_FRAME event handler function:

var rad:Number = angle * (Math.PI / 180); // Converting Degrees To Radians
orbiter.x = origin.x + radius * Math.cos(rad); // Position The Orbiter Along x-axis
orbiter.y = origin.y + radius * Math.sin(rad); // Position The Orbiter Along y-axis


If you test now, nothing will happen; this is because the variable angle is neither increasing nor decreasing. Therefore, we must increase or decrease the value:

angle += speed; // Object will orbit clockwise
angle -= speed; // Object will orbit counter-clockwise


Now what if we want our orbiter to continuously face a direction? Well I have written an equation to do just that!

orbiter.rotation = (Math.atan2(orbiter.y-origin.y, orbiter.x-origin.x) * 180 / Math.PI);


Depending on which way you have drawn your orbiter movieclip you may have to subtract a certain angle (outside the brackets) to get it to face the correct way.

Step 3: Transforming the Equation

Now this may sound crazy, but some of us might want to have our object orbit in an ellipse. This is easily doable; all we have to do is multiply in a specific place in the equation. Multiplying the cos or sin functions by a postive whole number will cause the circle to stretch. Multiplying it by a decimal between 0 – 1 will cause it to compress. And multiplying it by a negative will cause it to flip along that axis:

(2 * Math.cos(rad)); // Stretch the orbit along the x-axis by a factor of 2
(0.5 * Math.sin(rad)); // Compress the orbit along the y-axis by a factor of 2 (i.e. halve it)
(-3 * Math.cos(rad)); // Flip the orbit along the x-axis and stretch it by a factor of 3


We can also shift the orbit in any direction we want by adding or subtracting from the equation on either axis:

orbiter.x = (origin.x + radius * Math.cos(rad))-50; // Shift the orbit 50 pixels left on the x-axis


If you want to learn more about cos, sin, and atan2, take a look at Trigonometry for Flash Developers.

Step 4: Practical Uses for the Equation

Now this is all fine and dandy, but what can it actually be used for? A wide variety of things actually!

If you have ever played Mario Kart you would have gotten the “three shells” powerup; those shells are orbiting using this very technique. Another example is the widely over-used circle pong game, where the paddle orbits along a ring on the outside. A third example is from top down zombie shooter games: a lot of them include a powerup where a grouping of barrels orbits around your player and crushes any zombies if they are hit trying to attack you.

As you can see the use for this technique can be used in anything from industry standard games to casual games.

Conclusion

Thank you for taking the time to learn this Quick Tip! If you have any questions leave a comment below.

• http://www.igamesonline.com Mark

I don’t develop in AS, I just JS with jQuery and PHP/SQL to develop browser based games, but this was a great tutorial for helping me wrap my head around the math I needed to handle some ship rotation issues I was having.

Thanks for posting!

(PS: Would love to see less AS/Flash/HTML5 and more PHP/JS stuff on here!)

• http://michaeljameswilliams.com/ Michael James Williams

Regarding your PS: I think you’re looking for Nettuts+! Activetuts+ is for client-based coding of browser apps and games, with Flash, Unity, and HTML5/JavaScript; Nettuts+ covers general web development, including server-side stuff and more JavaScript :)

• http://www.igamesonline.net/ Mark

Maybe I am confused then – I thought when it said Browser Game and App Development it meant all languages…not just the snobbish plugin ones. Maybe you should update your category descriptions.

• s0ln0

What snobbish plugin? Haha, I didn’t know some plugins were snobbish?

• Alex

Nice explanation. Quick and concise. One tip though, you can say that you use the circle and elipse ecuations (parametric form) so people know where the calculations come from.

// Circle
X = r * cos t
Y = r * sin t
// or
X = Xc + r * cos t
Y = Yc + r * sin t
// where r is the radius, (Xc, Yc) coordinates of the circle’s center

// Elipse
X = a * cos t
Y = b * sin t
// where a is the major axis and b is the minor axis. Also can use the center coordinates.

• Jason

Very good article. Easy explanation, and much appreciated. Thanks for the FREE tutorial.

@Mark – there you go, that’s how you show gratitude for something that you like, that you appreciate someone who took the time to provide … for FREE. Next time, perhaps you might be more appreciative when someone is trying to help you.

• http://www.igamesonline.net/ Mark

Well now that I’ve been so thoughtfully advised by an employee that this section doesn’t and won’t ever apply to anything I’m doing – despite it’s titles to the contrary, I’ll probably just skip over this section from now on.

Great way to improve readership there.

• http://michaeljameswilliams.com/ Michael James Williams

Sorry if you felt we were misleading about what we taught. We’ve spent a lot of effort trying to make it clear that we now cover general browser-side development; I admit that “browser app and game dev” does not perfectly encapsulate what we cover, but honestly don’t know what else we could write that explains what we do.

• Neil

It’s a pretty simple formula, not rocket science. I’m writing in Java and this tutorial was a great quick resource for what I needed. If you know how to code then this is pretty easy to convert to any language or application.

• AGP

Thanks a whole lot. I, too, am writing in Java (as well as Objective-C) and found this very helpful. So should Mark.

• greenbug

I’m writing in AS3, I placed an ship that has bullets coming off it….

ship……
var myRadians:Number = Math.atan2(this.y – this.target.y, this.x – this.target.x);