Move with the vector

Hopefully you have read the Basics chapters and by now you know what are points, what are vectors and how to calculate different properties of the vectors. And you are patiently waiting to get your hands dirty with some vectors by using them in the actual game. Lets start and look how to use vectors to move object around.

In this example red dot is our object. You can change the x and y components of movement vector with arrow keys.

First we declare the object:

myOb={};
myOb.p0={x:100, y:150};
myOb.vx=3;
myOb.vy=1;

Starting point of object is at x=100, y=150 and the movement vector has values vx=3, vy=1. New position of object is at the vectors end point (p1) and it is calualted in the updateVector function. If you cant remember how to find values for p1, then please look up from the Point. Vector chapter. After movie clip has been placed correctly, we will set end point p1 as starting point for next calulations in the drawAll function.

Whenever arrow key is pressed, x or y component increased or decreased. getKeys and releaseKeys functions handle that. Main function runMe is run at every frame and it calls updateVector and drawAll functions to find new position and place the mc. In the example it also checks if the object has moved out of the stage area and if it really has, then it resets the object to opposite edge.

Remember never to use movie clips _x and _y properties as the values between calculations, it should always be final step to place movie clip on the correct coordinates after all calculation has been completed.

Frame or time

Lets look again in the updateVector function and see how the new coordinates for end point p1 is found:

var thisTime=getTimer();
var time=(thisTime-v.lastTime)/100;
v.p1={};
v.p1.x=v.p0.x+v.vx*time;
v.p1.y=v.p0.y+v.vy*time;
v.lastTime=thisTime;

Flash is frame-based program and it will try to execute all the animations and actionscript code as many times per second as set in the movie frame rate. It is common to use enterFrame clipEvent to handle all the calculations, but this is not actually good way. Lets suppose you have written code that increases objects x coordinate in every frame by 1. If you have set frame rate of your movie to 20, then the code is run 20 times in each second resulting the object to move 20 pixels in each second.

Or thats what you believe will happen. In reality no Flash movie is run at exact same frame rate. The frame rate is only maximum value and Flash player is trying to achieve it, but usually fails. Movies shown in the browser suffer because browser needs some CPU cycles, some computers are slower then others, people might have other programs running, all this will cause that usually frame rate will drop by 20-25%.

"So what?" you may wonder. It still runs, coordinates are still calculated, movie clips are still placed. Yes, but you are not in control of your game anymore. You can never be sure where the movie clip is after some time or at what speed it actually moves. If your Flash game is designed to test reflexes of the people and frame rate drops by 50% then people playing it at lower frame rate have huge advantage over people playing it at (almost) correct frame rate. This is common cheating method in Flash games, you can easily slow down the movie so it is very easy to do whatever is needed to win.

The solution of course is not to base your calculations on the number of frames, but on actual time. In frame-based game declaring speed vx=3 would mean movie clip will move by 3 pixels every time Flash player gets chance to run the movie. In time-based game declaring speed vx=3 will mean movie clip will move by 3 pixels in every second. In time-based game dropping frame rate doesnt make results unknown, you still know exactly where the movie clip is after 1 second, after 10 seconds or after 1 hour. Slower frame rate in time-based movie affects the smoothness of movement, object gets drawn on the stage less times in every second and the movement may become "jumpy", but every time object is drawn, it is drawn at exactly correct place.

We use getTimer function to find out the time:

var thisTime=getTimer();
var time=(thisTime-v.lastTime)/100;

getTimer returns number of milliseconds from the start of the Flash movie. In the movement calculations we need time from the last calculation so we reduce the last time from current time. And because time is measured in milliseconds, we need to divide it by 100 to get time measured in seconds. You could of course set the speed vector to use pixel/milliseconds too, but be aware that the actual values then will be quite small.

New coordinates for end point are then calculated using the time passed:

v.p1.x=v.p0.x+v.vx*time;

Lets see if this actually works. Suppose our movie clip is at x=150, y=100 and vx is 1. If frame rate is set to 20, then depending on the conditions variable time can be anywhere between 5 and 50 milliseconds. Lets say time is constantly 5 ms, which will give v.p1.x=v.p0.x+0.05 and after 20 moves in 1 second the object has moved 20*0.05=1 pixel. Which is exactly our speed vx. Now if time is 50, then new coordinate is calculated and movie clip is only drawn on stage twice in the second, but its final position is again 2*0.5=1 pixel.

You can download the source fla.

Acceleration

Just like speed vector changes objects position over time, acceleration vector changes objects speed over time.

So we set our objects acceleration vector to 0 at the start:

myOb.ax=0;
myOb.ay=0;

Now we check if arrow key is pressed and if it is, we change the x or y component of acceleration vector. In the update function we add acceleration vector to speed vector. Be careful when you use acceleration, if you dont limit your speed then after time the speed can grow and grow and grow.

v.vx=v.vx+v.ax;
v.vy=v.vy+v.ay;

Also notice that to completely stop the object its not enough to set speed vector to zero, you also need to set acceleration vector to zero or the object keeps moving.

You can download the source fla.

Next: Intersection.

Top