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
(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

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:

Setting Up Linkage
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):

(Either JavaScript is not active or you are using an old version of Adobe Flash Player. Please install the newest Flash Player.)

That’s it
I hope this tutorial helps you out and also teaches you a bit of actionscript.Download the files here.

2 Responses to “Flash Tutorial: Freeform Movement”


  1. Good style. Added links on my site

Trackbacks

  1. Objects following each other | guidance.lowicz.pl

Impart me with your input.

flourish