Simulating Physics...movement & friction in Adobe Flash ActionScript 2.0

Project 3

Your next project will be to create a game that is a little more involved that the ones you've been doing in the past. You will be using the mouse or the keyboard to control a character on the screen. You will learn to use random numbers and all about duplicating movie clips. I planned to make this an Asteroids style game like the one found here, but I will accept any game that meets the criteria specified in the project sheet. This will be a very complicated project, so don't even think about waiting until the last day to do it.

Movement Review

So far, we've been using actionscript to move objects around the screen and during our last game, we discovered how we can click and drag objects in flash. Some projects require you to allow users to control movement with the mouse or keyboard. In the breakout game we saw that we could create an object that followed the mouse movements using the _xmouse and _ymouse properties. To make something follow the mouse in flash, we can simply type in this actionscript:

onClipEvent(enterFrame)
{
    _x=_parent._xmouse;
    _y=_parent._ymouse;
}

That works pretty well, but what if we wanted to have some latency. The problem with the code above is that the object follows the mouse too precisely. What if we wanted the object to follow the mouse in a slower fashion like in the case of my asteroids game? In order to do that, we must build a friction function into the movement of the object.

Friction

Friction means moving the object not to the exact position of the mouse, but a little bit towards the position of where the mouse is located. The first thing we'll need to know is how far our object is from the mouse. We'll create two variables called difx and dify to figure out the difference between our mouse position and the position of the object.

Let's delete the code above and replace it with the code below:

onClipEvent(enterFrame)
{
dify=_root._ymouse-_y;
difx=_root._xmouse-_x;

_x=_x+(difx/5);
_y=_y+(dify/5);
}

There you have it, a simple function that incorporates friction. Notice how as the object gets closer to the mouse, it slows down. This is a pretty easy and effective way to create natural movement in your game.

Rotation

Unless your object was a square or a circle you might have noticed that the movement was a little unnatural because of the rotation of the object. Try drawing an object that's not uniform and you'll see what I mean. The object does not change direction when the mouse moves in a different direction. Things get much more complicated when we want this to happen.

Objects in flash have a _rotation property just like they have an _x, _y and _alpha property. This indicated the current angle in degrees of the current object. It's a property you can set and read. Let's try incrementing the rotation of our object in flash to see how this works. Make sure your object is asymmetrical so you can see a difference.

onClipEvent(enterFrame)
{
dify=_root._ymouse-_y;
difx=_root._xmouse-_x;

_x=_x+(difx/5);
_y=_y+(dify/5);
_rotation+=10;
}

This simply increments the rotation of the object by 10 everytime the object enters a frame. So your object should be rotating clockwise. What we really want is the object to move in the direction of the mouse movement.

Whenever we have two points on a coordinate system, if we draw a line between those two points, that line will have a certain angle to it. What we want is to calculate the angle of that line and feed it into our object so that it is oriented in the direction of that line. Flash provides a great function that does just that called atan2. It looks like this.

angle=Math.atan2(y,x);

There is a problem with this function though, it returns the angle in radians and if we want to set the rotation of an object, we have to do it in degrees. You can convert radians to degrees by multiplying the radians by (π/180) or in Flash nomenclature:

Math.PI/180;

So the whole bunch of Actionscript to make our object move in the direction of the mouse would look like this.

onClipEvent(enterFrame)
{
dify=_parent._ymouse-_y;
difx=_parent._xmouse-_x;

_x=_x+(difx/5);
_y=_y+(dify/5);
// Calculate the angle
myangle = Math.atan2(dify, difx)*180/Math.PI;
_rotation=myangle;
}

It really seems like it should be harder than that, but that's it.

Keyboard Movement

We've covered movement with the mouse, but how do we move an object with the keyboard? Let's start a new file and take a look at how you can accomplish this easily.

To check for keyboard input, flash provides the built in Key object. We can check to see wether a specific key is being pressed by checking the isdown method of the key object. Let's make some actionscript that checks for the up and down arrows on your keyboard to control acceleration/deceleration in the X direction of an object

onClipEvent(load)
{
    acceleration=0;
}
onClipEvent(enterFrame)
{
    if (Key.isDown(Key.UP))
        {
            acceleration++;
        }
    if (Key.isDown(Key.DOWN))
        {
            acceleration--;
        }
    _x+=acceleration;
}

This will work just fine. If you want the rotation to be affected by the left and right keys, it gets a lot more complicated. Take a look at the code below:

onClipEvent(load)
    {
        acceleration=0;
    }
onClipEvent(enterFrame)
    {
        if (Key.isDown(Key.LEFT))
            {
                _rotation-=10;
            }
        if (Key.isDown(Key.RIGHT))
            {
                _rotation+=10;
            }
        if (Key.isDown(Key.UP))
            {
                acceleration++;
            }
        if (Key.isDown(Key.DOWN))
            {
                acceleration--;
            }
        myangle=_rotation;
        xmov=Math.cos(Math.PI/180*myangle)*acceleration;
        ymov=Math.sin(Math.PI/180*myangle)*acceleration;
        _x+=xmov;
        _y+=ymov;
    }

We had to use the cosine and the sine math function to get our movement to act right.

Next week, we'll talk about spawning and random object generation.