Using Tweens in ActionScript 3

February 24th, 2010

Last week ActiveTuts put up a quick tutorial about building a sliding menu paddle, which isn’t anything too complicated but it was the first time I’d done anything with the built in Tween Class in ActionScript 3. Usually I’d use something like Tweener or TweenMax, but I thought I would see what you could do with this. What I decided to make was something that I would have loved to have been able to make with code when I was just beginning to learn AS3, a Flash site with sliding content. This would have been something I would have used movieclips I created in Flash and then created keyframe tweens to get the effect I wanted. This isn’t the most complex thing to create but it will help out beginners.

Here’s what we are going to build:

Start a new Flash file (AS3), mine’s the default – 550×400 with a white background and the framerate at 24. This is about the functionality, not the design, you can add that in after you get the all working. Save it as whatever you want, I called mine TweenSite.fla. Next, using the Text tool (T), type out something like button 1 on the stage. Make sure the button is set to Dynamic Text and the instance name is buttonText. This will allow us to control what the button says in our ActionScript file.

Now turn the text into a movieclip, F8 or Modify > Convert to Symbol. Call it MyButton, set the registration point to the top left and check the Export for ActionScript box.

Delete the MyButton from the stage, we’re going to add it using ActionScript. Finally, one the Document Class field, type Main. This will link our ActionScript file to the .fla. If you don’t know how the document class works, there’s a great video at gotoAndLearn.com.

And that is everything we are going to make in the .fla. Everything else now will be created with ActionScript.

Create a new ActionScript file, File > New… > New ActionScript File. Call it Main and save it in the same folder as your .fla. Instead of writing all the code in the .fla or even in just one .as file, we are going to build this OOP style, to make it easier to customize after it’s been built.

Here’s the code we are going to start with in Main.fla:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package
{
    //We have to import the classes we are going to use
    import flash.display.MovieClip;
   
    public class Main extends MovieClip
    {
        //This creates an instance of the button we made
        private var button1:MyButton = new MyButton();
       
        public function Main():void
        {
            //This calls the init function which gets everything going
            init();
        }
       
        private function init():void
        {
            //This adds the button to the stage
            addChild(button1);
        }
    }
}

If you test this now, you should just be able to see the bottom and right side of our button. This because the position of something added to the stage is automatically 0,0. So just add this under addChild(button1):

1
2
button1.x = 30;
button1.y = 50;

This just positions our button the stage. Now to make this work the way we want to, we need more than one button, up with the other variable add this:

1
2
3
private var button2:MyButton = new MyButton();
private var button3:MyButton = new MyButton();
private var button4:MyButton = new MyButton();

What we’re doing here is making three more instances of the same button, but we’ll use our code to change the text. Underneath button.y = 50 add this:

1
2
3
4
5
6
7
8
9
addChild(button2);
button2.x = 30;
button2.y = 90;
addChild(button3);
button3.x = 30;
button3.y = 130;
addChild(button4);
button4.x = 30;
button4.y = 170;

Here we are adding the three other buttons to the stage and positioning them 40 pixels apart. Now if you test it, the buttons will all line up vertically but they all say button 1! So, how do we fix that? At the bottom of the init function add this:

1
2
3
4
button1.buttonText.text = "Button 1";
button2.buttonText.text = "Button 2";
button3.buttonText.text = "Button 3";
button4.buttonText.text = "Button 4";

Now if you test the movie, the text should have changed to what we have here. Now as it stands now, our “buttons” don’t really act like buttons. If you mouse over them, you won’t get the hand cursor that tells people that it’s a clickable button. We can fix this a couple of ways. One way would be in our Main.as file to set the buttonMode to true and something called mouseChildren to false for each button, but that would be a lot of code, and if we wanted to change something, like the names of buttons, we would have to change a lot. The simple way to do this is to make a new ActionScript file and put the settings in there. So create a new ActionScript file and save it as MyButton in the same folder as our other files. If you named your button something else, you have to name this file the same as your button because our Main file is going to import these settings and apply them to our buttons. Here’s the entire code for our MyButton.as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package
{
    import flash.display.MovieClip
   
    public class MyButton extends MovieClip
    {
        public function MyButton()
        {
            //This gives movieclips the same properties as buttons, so the hand cursor appears
            buttonMode = true;
            //This stops the text from inside the MyButton movieclip from being selectable
            mouseChildren = false;
        }
    }
}

Now if you test the movie, you’ll see that now the hand cursor appears and the text isn’t selectable. This is the main advantage of OOP, with a few lines of code, we have affected our entire navigation. Now, let’s add the gray block to our movie. Create a new ActionScript file and save it as Block.as. Here’s the code for Block:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package
{
    import flash.display.MovieClip;
   
    public class Block extends MovieClip
    {
        public function Block()
        {
            //Draws the block using actionscript to keep file size down
            //First part is color, second is the alpha
            graphics.beginFill(0xCCCCCC, 1);
            //This draws a rectangle(x,y,width,height)
            graphics.drawRect(0,0,102,36);
            graphics.endFill();
        }
    }
}

Now back in Main.as we have some code to add. First add this up with the other variables:

1
private var block:Block = new Block();

Same as with the buttons, we are creating an instance of our Block class. Next in the init function, at the top, before all the buttons put this:

1
addChild(block);

Now at the bottom of the init function add this:

1
2
block.x = button1.x;
block.y = button1.y;

Now when we test our movie, the block will appear behind the top button. Next we’ll give our block something to do, at the top where we are importing the MovieClip class add this:

1
2
3
import flash.events.MouseEvent;
import fl.transitions.Tween;
import fl.transitions.easing.*;

This is going to allow us to have mouse events and tween events in our Flash movie. Next with our other variables, add this:

1
private var barY:Tween;

Here we are creating our first tween. Now we need to tell our tween what to do:

1
2
3
4
5
private function onNavClick(e:MouseEvent):void
{
    //First we say what to tween, what property to affect, set what kind of ease(if any) we want to use, where to start the tween, where to end, how long to take, and the true means the time is in seconds, if it's set to false the tween is in frames
    barY = new Tween(block, "y", Back.easeOut, block.y, e.target.y, 1, true);
}

I’ve described what the Tween does in comments in the code. Next we need to add some listeners to call this function so it actually does something, what I usually do with listeners is create a function addListeners():

1
2
3
4
5
6
7
private function addListeners()
{
    button1.addEventListener(MouseEvent.CLICK, onNavClick);
    button2.addEventListener(MouseEvent.CLICK, onNavClick);
    button3.addEventListener(MouseEvent.CLICK, onNavClick);
    button4.addEventListener(MouseEvent.CLICK, onNavClick);
}

We need to add a listener to each button so that the block knows which button to go to. Inside the Main function add:

1
addListeners();

Now if you test the movie, you should get this:

OK, now let’s make those buttons control something. What we are going to do is just make four big blocks that slide into view. Once again, we aren’t designing anything we are just building the functionality. The block can be easily replaced with images, movieclips or external .swfs. To do this we are going to make a new ActionScript file and call it ContentBox.as. We’re going to make all the boxes in on class instead of making a separate one for each box. It’s just easier and it’s not too hard to build more custom classes for your own stuff later. Here’s the code for ContentBox:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package
{
    import flash.display.MovieClip;
   
    public class ContentBox extends MovieClip
    {
        public function ContentBox()
        {
            graphics.beginFill(0x999999,1);
            graphics.drawRect(0,0,345,360);
            graphics.endFill();
            graphics.beginFill(0x666666,1);
            graphics.drawRect(345,0,345,360);
            graphics.endFill();
            graphics.beginFill(0x333333,1);
            graphics.drawRect(690,0,345,360);
            graphics.endFill();
            graphics.beginFill(0x000000,1);
            graphics.drawRect(1035,0,345,360);
            graphics.endFill();
        }
    }
}

Really simple stuff here, we’re just creating four boxes that are 345 by 360 and positioning them along the x-axis. I’ve also made each one a different shade of gray that way we can see the boxes move but we won’t blind ourselves with bright colors. Next, up with the variables, put this:

1
private var contentBox:ContentBox = new ContentBox();

And at the bottom of the inut function, add this:

1
2
3
addChild(contentBox);
contentBox.x = 185;
contentBox.y = 20;

Same stuff we did with the buttons, so you should know what’s going on here. If you test your movie now, you’ll see the first box and part of the second box, which isn’t really what we want, we just want to see the first box. To do this, we’ll just add a mask to our stage. Make a new ActionScript file and save it as MyMask.as. Here’s the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package
{
    import flash.display.MovieClip;
   
    public class MyMask extends MovieClip
    {
public function MyMask()
        {
            graphics.beginFill(0xFF0000,1);
            graphics.drawRect(0,0,345,360);
            graphics.endFill();
        }
    }
}

Pretty much the same as our ContentBox class, but with this our mask, the color isn’t going to matter. Now back in our Main.as file, add this code up with the other variables:

1
private var myMask:MyMask = new MyMask();

And then add this at the end of the init function:

1
2
3
addChild(myMask);
myMask.x = 185;
myMask.y = 20;

Now if we test this, there’s a red box over top of the first gray box, which I don’t think is quite what we’re going for here. So let’s add this line of code right under the last stuff we added:

1
contentBox.mask = myMask;

Now if we test it, the first gray box is back and we can’t see the other box anymore. Now we have one final thing to do and it’s not that major, we’re just going to apply the Tween code we used on our navigation to the boxes to make them slide into view when a button is clicked. First off, add this to your other variables:

1
private var contentX:Tween;

Next we need to add these listeners, which are pretty much the same as the other listeners, they are just calling another function:

1
2
3
4
button1.addEventListener(MouseEvent.CLICK, moveContent);
button2.addEventListener(MouseEvent.CLICK, moveContent);
button3.addEventListener(MouseEvent.CLICK, moveContent);
button4.addEventListener(MouseEvent.CLICK, moveContent);

Now we have to make the moveContent function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private function moveContent(e:MouseEvent):void
{
    if (e.target == button1)
    {
        contentX = new Tween(contentBox, "x", Regular.easeIn, contentBox.x, 183.95, 1, true);
    }
    if (e.target == button2)
    {
        contentX = new Tween(contentBox, "x", Regular.easeIn, contentBox.x, -161.55, 1, true);
    }
    if (e.target == button3)
    {
        contentX = new Tween(contentBox, "x", Regular.easeIn, contentBox.x, -507.10, 1, true);
    }
    if (e.target == button4)
    {
        contentX = new Tween(contentBox, "x", Regular.easeIn, contentBox.x, -852.65, 1, true);
    }
}

Here we’re just using if statements to see which button was clicked and then telling contentBox what to change it’s x value to. Now if you test the movie you’ll see contentBox slide to the color that corresponds with the button we clicked on.

I hope this helped you out, this framework should be pretty easy to customize and allow you to build stuff pretty quickly.

Leave a Reply

Your email address will not be published. Required fields are marked *