January 16th 2008
Flash Tutorial: Freeform Movement
Introduction
The idea of freeform snake-like movement is shown in games such as flOw, and my two games, Worms and Worms V2.
This type of movement, with objects following each other, creates a cool effect, but is not often demonstrated. Here I will show you how to make a snake-like creature that follows your mouse.
Final Effect
Setting Up
You will need a .fla and an .as. In your .fla you will need an movieclip (the part on the snake) with a class by the title of your .as file. In example, if you had part.as for your .as file, you would have to have the properties of your movieclip be like so:

The .as file
So then in your .as file, you will need to start with:
class Part extends MovieClip{
in this line, ‘Part’ must be the name of your .as file (so in this case, it’s part.as).
Continuing, you want to define the variables:
var targ:Number = 0;
var distx:Number = 0;
var disty:Number = 0;
‘Targ’ will be used to determine what the part is following, 0 = mouse, 1+ = the part before it. ‘distx’ and ‘disty’ will be used when finding the distance between two parts. Moving on, we have our onEnterFrame function:
function onEnterFrame()
{
Start with the function set up
if (targ == 0) {
distx = _root._xmouse - _x;
disty = _root._ymouse - _y;
var angle:Number = Math.atan2(disty, distx);
_rotation = angle * (180 / Math.PI);
_x += distx * .10;
_y += disty * .10;
Here we start with an if statement that checks to see if the target is the mouse. If it is, it defines the ‘dist’s as the difference between the mouse’s location and the part’s location.
The next part finds out the proper rotation between them. The last two lines tell the part to go 1/10 of the distance between the part and the mouse, which allows for a nice braking effect. If you want it to go faster, increase what distx and disty are multiplied by, but keep the number constant and keep it below 1 (slower, decrease the number, keep it above 0). Now:
} else{
var tm = “p” + targ;
distx = (_root[tm]._x - (Math.cos(_root[tm]._rotation * Math.PI / 180) * 5)) - _x;
disty = (_root[tm]._y - Math.sin(_root[tm]._rotation * Math.PI / 180) * 5) - _y;
var angle:Number = Math.atan2(disty, distx);
_rotation = angle * (180 / Math.PI);
if (Math.abs(distx) < 10) {
distx = 0;
}
if (Math.abs(disty) < 10) {
disty = 0;
}
_x += distx * .10;
_y += disty * .10;
}
}
We start by having an ‘else’ statement since the last part of code, with the if statement never had a closing bracket. This section of code applies to anything other that the part following the mouse. This first part says the variable ‘tm’ is ‘p’ with the target number; we assume here that all your parts are named ‘p’ followed by a number on the .fla, i.e. p1 follows the mouse, and p2 follows p1.
These next two lines of code, (appears to be four, because it does not fit) finds the distance between the part and a bit before the next part. Because the part follows a bit before the back of the part before it, it does not come it will not come in at strange angles.
The next two lines are the same as before, and they define the rotation. These next if statements make the part stop before it touches the part in front of it so it has a bit of spacing. Finally, these last lines, same as before, make the snake move 1/10th of the distance. Next we have:
function initiate(num:Number)
targ = num;
}
}
I’ll explain this code in a bit.
Final Code for the .as file
class Part extends MovieClip{
var targ:Number = 0;
var distx:Number = 0;
var disty:Number = 0;
function onEnterFrame()
{
if (targ == 0) {
distx = _root._xmouse - _x;
disty = _root._ymouse - _y;
var angle:Number = Math.atan2(disty, distx);
_rotation = angle * (180 / Math.PI);
_x += distx * .10;
_y += disty * .10;
} else{
var tm = “p” + targ;
distx = (_root[tm]._x - (Math.cos(_root[tm]._rotation * Math.PI / 180) * 5)) - _x;
disty = (_root[tm]._y - Math.sin(_root[tm]._rotation * Math.PI / 180) * 5) - _y;
var angle:Number = Math.atan2(disty, distx);
_rotation = angle * (180 / Math.PI);
if (Math.abs(distx) < 10) {
distx = 0;
}
if (Math.abs(disty) < 10) {
disty = 0;
}
_x += distx * .10;
_y += disty * .10;
}
}
function initiate(num:Number){
targ = num;
}
}
The .fla File
It may seem odd that I’m getting to the .fla file after the .as file, but that is because I needed to show the initiate. On the frame with your parts, (we continue to assume they are named ‘p’ followed by the number of the place they are in the chain) in the actions window, write:
p1.initiate(0);
p2.initiate(1);
For every part you have, write the movieclip instance name followed by ‘.initiate(’ then add the targ number, (which should be the in the instance name -1, i.e. p ‘43′ would be p43.initiate(43).) then finally at the end ‘)’. by saying thi, you use the initiate function to define what the targ number is. Note: Anytime you add a new part to the stage, you must ‘initiate’ it.
Final Effect
Here is an example of this effect in use (click on the .swf or reload the page to make the snake come):
That’s it
I hope this tutorial helps you out and also teaches you a bit of actionscript.Download the files here.

Subscribe to Design Apex
On August 25th, 2008 Pablo Said:
Good style. Added links on my site