Jesse lives and works in Melbourne Australia. He is the Cofounder of http://ActionScript.org. A Flash enthusiast, teacher, author, freelancer and speaker Jesse's main focus nowadays is managing http://ActionScript.org, but he enjoys participating actively in community and the wider Flash scene when he has time. Download the source for the above movie here. (Zipped, PC Flash 5 file).
Believe it or not I get enough questions about making smooth actionscript based tweens to dynamic X and Y positions, and/or random tweens to dynamic X and Y positions, that I've decided to write a tutorial. This tutorial will cover how to make an object move smoothly to a specified place on the stage using Actionscript. This place can be specified by the user clicking, or entering numbers, or can be generated randomly. Let's take a look shall we?
The primary application of this kind of stuff is in games and navigations. Then again I say that about most Actionscript. I've only ever used it in games but I'm sure it can be used in navigations also, somehow :o) Above I've an example of how we can make an object move smoothly and randomly, and later I will show you how we can make it move smoothly to a user-specified position. The best part about these two examples is that they both use the same code (almost) and it's very straight forward.
OK, say you have an object on the stage and you want to move it around randomly. Those of you who are a bit more experienced or creative may also realize that this will require generating random X and Y positions (_x and _y). What most people fall down on is how on Earth to make the animation smooth. We don't want our object to just jump from one _x, _y tuple (a tuple is a group of terms or variables) to another, we want it to animate there. This is deceptively simple also, once you see it done. This tutorial will outline a few methods of achieving the smooth movement effect.Sounds simple huh? I think most of you could go off an make your own working example now, but the next problem people face is the syntax because it does get a bit ugly the way some people do it. I've kept it as clean as possible.
Now that we know the logic, let's go back to our example. Grab the source for the movie above. As always, if you can't open my source you're going to have to build it yourself. Those of you with the source can skip this bit. Those without please construct the following:
Before we go any further, let me explain why I'm using a looping movieclip. Those of you using Flash 4 don't have many options really. In Flash 5 we could use an enterFrame clip event but there isn't any clean way of stopping a loop of that form, meaning when you want your ball to stop, you're going to have to use another conditional and you'll be using some additional overhead for each new frame your movie hits. Those of you using Flash MX who have read my Intervals tutorial might see this is another great application for Intervals. I'm not using them here though because showing this method makes the tutorial more universal, and you're all smart enough cookies to make the necessary changes if you decide to use Intervals, I'm sure.
OK, now you all have a working source file, so let's take a look at how it works. All the script is in the controller clip so we'll just go frame by frame through that:
What it does and how (line by line):
Frame 1:
[as]loops = 0;Going back to our rules for random movement, we've now established the fundamentals. We know where we are, where we're going, how many steps it's going to take, and how big each step will be. Now it's time to start stepping! That's where frames 2 and 3 come in.
Frame 2:
[as]loops++;So now our object has moved a few pixels in the x and y directions. Basically we just have to keep moving it until it reaches its target. We determine if it's yet reached its target in Frame 3. Note that the first 3 lines of Frame 3 are the same as those in Frame 2. This is so we get some movement every frame, and it makes our tween more smooth.
Frame 3:
[as]loops++;And of course, in frame 1, we generate another random target and the whole process starts over!.
"That's all very well Mr. Jesse, but I don't want to just move a ball randomly around the screen. I have this scenario where I want a user to input a location (via clicking there or entering values in a text field) and then I want the object to move to that location! Can you help me too?"
Surely can. Let's take a look, over the page.
Click anywhere on the stage below and watch it happen.
Grab the source for this one here. (Zipped, PC Flash 5 file).
In the example above, our obedient little clip moves where-ever we tell it. And it's smart too, if we tell it to move somewhere else while it's still moving, it does just that, but it doesn't get confused with how many steps it's taken already. Clever little circle! Let's take a look at the code.
This one is handled by the same mechanism as the random mover. The differences here include:
So, instead of having a random() function generate our target _x and _y, we read them in when the user clicks somewhere. I've done this with an invisible draggable button with the following code:
[as]on (release) {Notice that this button takes the place of our Frame 1 in the random mover example. Let's examine the code.
What it does and how (line by line):
This last line, begins our controller clip looping. The controller clip in this example is very much like that of the previous example; it goes ahead and increments the _x and _y until we've taken the right number of steps. However, we have to include some extra code for this scenario: What if the user clicks one place, and before our movie clip gets there, clicks another? Well our obedient little clip wants to go to the latest place, but it's already taken maybe 5 steps and it's been told to only take 20 steps. So it has 15 steps left, but each step is 1/20th the distance to the target. The result? It wont reach the second target. This is where the extra code comes in.
The variable running is true while our controller clip is looping. Once the looping is finished, it's set back to false. So if someone clicks this invisible button while the controller is looping (while the circle is moving), we must set the number of moves available back to 20 so as not to confuse our little circle. This is the reason for the code on the button which states:
[as]if (_root.running == true) {What it does and how (line by line):
Frame 1:Frame 3:
[as]loops++;So frames 2 and 3 loop between each other until we reach our chosen destination, at which point they jump back to frame 1 and the clip stops.
And if the user clicks while it's in motion? Well since running == true, it sets the number of moves back to 20, sets the xdiv and ydiv variables to their new values and off it goes again! Smart users could implement this technique in a Mouse Chaser with Delay sort of scenario. Just have a looping MC which continually gets the mouse _x and _y and sets them as the target for the clip... But that's for another tutorial. Cheers!
| Jesse Stratford [email:jessestratford@actionscript.org] is the Co-Master of ActionScript.org and a freelance Flash developer and teacher. He is based in Australia and enjoys all things Flash. NB: If you have comments or feedback please feel free to email me, but please do not email me Flash questions; the forums are provided for that purpose and you will get a faster answer by posting you question there. |
If you have found this tutorial helpful, I hope that you will take 30 seconds to visit The Hunger Site where, with just one click you can make a free donation of food to a starving person in a third-world country. We do not benefit financially from this action; it is purely an act of charity. |
| This tutorial is protected by International Intellectual Property Rights laws and may not be reproduced or redistributed in full or part, without the prior written consent of the author. Unauthorized reproduction of this tutorial or its contents may result in prosecution. I've worked hard on this tutorial, please don't steal it. |