| Moving objects in flash using vectors |
| Written by Petar Jercic | ||||
Moving objects in flash using vectorsThere are many tutorials out there teaching you how to move objects in flash using Actionscript. They are all pretty good and use the same technique. That technique is to add/subtract some value every iteration (frame) to X and Y coordinates of the object, depending on the arrow key you pressed. That gives the illusion of object moving.
While this is a simple solution, there is an even simpler and more powerful solution. Name of that solution is vectors. What is a vector?![]() Simply put, vector is a line indicating direction and length of the movement. We assign vector to some object so we know where to and how much to move that object. ![]() We write vectors as v=<x,y> (we say that vector has a x – component and the y – component) so the vector on the picture would be v=<7,6>. This means that the object has to move 7 units on the X axis, and 6 units on the Y axis to get where the vector is pointing. See how simple it is. Why is a vector better than the example at the beguining?![]() The example at the beginning adds speed of 4 to X or/and Y axis if we press an (up, down, left, right) arrow. If we press two arrows at the same time, for example up and right, we move up 4 units, and right 4 units. So we end up (up & right vector) farther than the ball could actually move. Try it in some older games, moving to 45° angles is much faster than moving front or sides. You can see this directly in the picture, the 'up & right' vector is longer than the 'up' or 'right' one. Note that, with this solution, we can move at right angles or 45° sides ONLY. ![]() Vector solves this problem. If we say that the ball moves 4 units, it is her speed for one iteration. And if we go to the sides we should distribute this speed to X and Y axis. This is where normalization of the vector comes in play. Normalizing vector means that vector keeps his direction, but its length is default 1 unit or whatever we specify. Fortunately flash does that for us so you just need to specify how long do you need the vector and presto, you have it. We are going to use normalize(length) flash method to normalize vector to some desired length, 4 units in our previous example normalize(4). ![]() Now all you have to do is add vector x – component to X axis of the object, and y – component to Y axis. And your object moves at the same speed whatever direction you need it to go. We are no longer constrained to sides or right angles. Let's walk you through an example. We want to place a ball in the middle of the screen and make a vector that is tracing your mouse (red vector).We are also going to normalize that vector so you can see normalization in play (green vector). When you click on the screen the ball moves according to that vector. Of course we will normalize it further to some smaller value so the ball doesn’t rocket off screen before you can see it. Let's look at the code.
First let's set some variables we will use later. Function onLoad runs only once at the start of the movie. Depth 'ballDepth' at which we will display the ball, 'ballObject' with the ball attached. And finally we set the ball idly sitting in the middle of the screen. But not for long.
Then every frame (iteration) we do the following. Function onEnterFrame runs once every frame, and you can set how many frames per second there are, I use 30 fps. Clear the screen, which contains vectors drawn in the previous frame so we can draw new ones for this frame. Check if the user clicked on the screen (Key 1 is the left mouse button) and if the ball is idle (isn't already moving). If that’s true, we change the state of the ball so it can start moving.
If the ball is idly standing, we create vectors and draw them. Vector is defined by Flash class Point and has an x & y component, as we said before. That is Point(x-comp, y-comp). We have to subtract position of the ball from the mouse position since it is sitting in the middle of the screen. That way we get exact distance of the mouse from the ball. First we draw the vector from ball to your mouse cursor (red color). Then we normalize it to 50 units long, so you can see normalization in real time when we draw it (green color). That vector will always be 50 units long. And finally we normalize the vector to some small value so the ball doesn't rocket off the screen if you click on the screen. This final vector is used for moving the ball when you click on screen, so we don't need to draw it. The first two drawn vectors are just for show so you can see how the vector works.
If the ball is in the moving state (move), we just add x and y component of the vector to x and y position of the ball, and the ball moves every iteration according to the direction and length (speed) of the vector. If the ball exits the screen we reset it to the middle of the screen and set it idly sitting there. Full code is here:
Don't worry about the function 'drawLine' it is just used to draw the vectors in different colors on screen. We used it when we needed to draw those two vectors. CollisionThe only thing left is hitting your balls against the wall. Now here is a great example of how to use the newly learned knowledge of vectors. We just have to know the direction and speed of the ball so when the ball bounces off the wall we just send it flying the same speed in different direction (alternatively you could slow the ball a little bit when it bounces to simulate losing speed in the bounce).
What do we know so far? We can launch the ball in any direction using vector. We can limit the ball's speed to some desired value using normalization. Now let’s work out what happens when the ball hits the wall (it rhymes :).
First (no. 1) we have the ball speeding towards the wall with some direction and speed. That information is contained inside the vector v=<7,-6>. Second (no. 2) upon hitting the wall we have to reflect the incoming vector regarding axis the wall lies on. In example on the picture the wall lies on Y axis so we have to reflect vector's x – component from 7 to -7. And now we have a reflected vector. We are going to work with right angle walls so we don't have to calculate incoming angles, to make it simple. If the wall lies on Y axis, we just reflect (that just means reverse) x – component of the vector, and if it lies on X axis, we have to reflect y – component. Third (no. 3), in the next iteration reflected vector will send the ball bouncing off the wall keeping it's angle of incidence. Let's walk you through an example. We want to place a ball in the middle of the screen and make a vector that is tracing your mouse (red vector).We are also going to normalize that vector so you can see normalization in play (green vector). Of course we will normalize it further to some smaller value so the ball doesn’t rocket off screen before you can see it. When you click on the screen, the ball instance goes to array of all the balls on the screen. Then we move all the balls according to their direction vector. We don’t move the newly created ball in the middle of the screen. Let's look at the code.
First let's set some variables we will use later. Function onLoad runs only once at the start of the movie. Depth 'ballDepth' at which we will display the ball. Array ' balls' with all the balls currently on the screen. Finally we set the ball sitting in the middle of the screen, and we save its reference in the 'balls' array using push method. Push method just puts a given object in the array. Name of the instance " ball_mc"+balls.length has to be unique, so that’s why we use counter of the length of the array, “ball_mc1”, “ball_mc2”, “ball_mc3”, … . Depth "ballDepth+balls.length" has to be unique also, “101”, “102”, “103”, … .
Then every frame (iteration) we do the following. Function onEnterFrame runs once every frame. Clear the screen, which contains vectors drawn in the previous frame so we can draw new ones for this frame. Check if the user clicked on the screen (Key 1 is the left mouse button) and if he did, the magic happens. We assign last normalized vector2target vector to a ball instance that is in the middle of a screen waiting for your click, so it knows where and how fast to move. Then we put the new ball on the middle of the screen and in the array, waiting for your click patiently.
Then every ball in the array, that is on the screen, we move according to their direction vector assigned to them earlier. First we check if the ball hit the wall, and if it did, reverse the vector as explained before. For side (Y axis) walls we reverse x – component, balls[i].direction.x = -balls[i].direction.x;, and for the top/bottom (X axis) wall we reverse y – component, balls[i].direction.y = -balls[i].direction.y;. After that we just add x and y component of the direction vector to X and Y position of the ball, and the ball moves every iteration according to the direction and length (speed) of the direction vector.
This part is the same as in the last example, drawing of the vector, and a normalized one form the ball in the middle of the screen to the mouse. And finally normalizing that vector to 5 units used for moving (direction vector) of the balls. Full code is here:
Marble box is a full blown game with this vector engine explained here, so check it out to see how it woks perfectly. Now you are ready to move your objects using vectors. Thanks for reading this tutorial. I hope it helped. Comments (0) |