Posts Tagged ‘actionscript’

Make a resizable, movable box in Flash

Thursday, April 29th, 2010

I’m going to show how to make a box that you can resize by dragging the corners. It’s not that hard but it does take some figuring out to get it to work right. Here’s what we’re going to make:

Download the files.

Start off with a new Flash file. And build this on your stage. The red box can be four instances of the same movie clip. For the document class, put ReSizerControl.

Create a new ActionScript file and use this code as the base for it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;
   
    public class ReSizerControl extends MovieClip
    {
       
        public function ReSizerControl()
        {

        }
    }
}

Save this as ReSizerControl.as in the same folder as your .fla file.

What we’re going to do here is make functions to control the resizing when the corners are moused down on. But we’re also going to make it so we can move the black box around the stage which makes it a bit more difficult to set up the resizing functions. I’m going to put most of the explanations in the code, so that if you need to use this later, you’ll still have that info in there. The first thing, we’re going to do is get the bottom right corner to resize the box when you drag it around.

First, inside the constructor function, ReSizerControl(), put this:

1
2
//adds the listeners to the stage
addListeners();

Next, below ReSizerControl(), create this function:

1
2
3
4
5
6
private function addListeners()
{
    reSizer_br.addEventListener(MouseEvent.MOUSE_DOWN, onResizerDown);
    reSizer_br.addEventListener(MouseEvent.MOUSE_UP, onResizerUp);
    reSizer_br.buttonMode = true;
}

Ok, not we have to create the functions, onResizerDown and onResizerUp. They’re going to be pretty similar, one activates the resizing and the other one cancels it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private function onResizerDown(e:MouseEvent):void
{
    //create a variable that we can use to check which red block has been clicked on
    //converts the name of the object to a string so we can check it
    var targetName:String = e.target.name.toString();
    //checks to see if the red block being clicked on is the one called 'reSizer_br'
    if (targetName == 'reSizer_br')
    {
        //if it is, then add the listener for reSize_br
        addEventListener(Event.ENTER_FRAME, reSize_br);
        //enable the user drag the clicked on block around the stage
        e.target.startDrag();
    }
}

private function onResizerUp(e:MouseEvent):void
{
    var targetName:String = e.target.name.toString();
    if (targetName == 'reSizer_br')
    {
        //Removes the listeners and stops the box from changing size
        removeEventListener(Event.ENTER_FRAME, reSize_br);
        e.target.stopDrag();
    }
}

Now that we have that, we have to create the reSize_br function, but first we need this below the ReSizerControl extends MovieClip and about the ReSizerControl function:

1
2
3
4
private var blockWidth:Number;
private var newWidth:Number;
private var blockHeight:Number;
private var newHeight:Number;

These variables are going to enable us to resize the block’s width and height. Here’s the reSize_br function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
private function reSize_br(e:Event):void
{
    //finds the mouse position and resizes the black box
    if (mouseX > block.x + 20)
    {
        newWidth = reSizer_br.x;
        blockWidth = newWidth - block.x;
        block.width = blockWidth;
    }
    if (mouseY > block.y + 20)
    {
        newHeight = reSizer_br.y;
        blockHeight = newHeight - block.y;
        block.height = blockHeight;
    }
    //checks if the red block is too close another one and stops it from moving
    if (mouseX < block.x + 20)
    {
        reSizer_br.x = block.x + 21;
    }
    if (mouseY < block.y + 20)
    {
        reSizer_br.y = block.y + 21;
    }
}

Now if you test it, it should allow you to drag the bottom right red block and resize the block box. Now let’s make the bottom left one work. Add this to the addListeners function:

1
2
3
reSizer_bl.addEventListener(MouseEvent.MOUSE_DOWN, onResizerDown);
reSizer_bl.addEventListener(MouseEvent.MOUSE_UP, onResizerUp);
reSizer_bl.buttonMode = true;

And this to the bottom of the onResizeDown function:

1
2
3
4
5
if (targetName == 'reSizer_bl')
{
    addEventListener(Event.ENTER_FRAME, reSize_bl);
    e.target.startDrag();
}

And this to the bottom of the onResizeUp function:

1
2
3
4
5
if (targetName == 'reSizer_bl')
{
    removeEventListener(Event.ENTER_FRAME, reSize_bl);
    e.target.stopDrag();
}

And here’s our reSize_bl function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
private function reSize_bl(e:Event):void
{
    if (mouseX > 0)
    {
        block.x = reSizer_bl.x;
        blockWidth = reSizer_br.x - block.x;
        block.width = blockWidth;
    }
    if (mouseY > block.y + 20)
    {
        newHeight = reSizer_bl.y;
        blockHeight = newHeight - block.y;
        block.height = blockHeight;
    }
    if (reSizer_bl.x > (reSizer_br.x - 20))
    {
        reSizer_bl.x = (reSizer_br.x - 21);
    }
    if (reSizer_bl.y < (block.y + 20))
    {
        reSizer_bl.y = (block.y + 21);
    }
}

The reSizer_bl function is pretty much the same, just minor differences in how it resizes the black box. Figuring out the differences will really help you understand how this works. Now, let’s get the top two red blocks working. Add this to the onResizeDown function:

1
2
3
4
5
6
7
8
9
10
if (targetName == 'reSizer_tr')
{
    addEventListener(Event.ENTER_FRAME, reSize_tr);
    e.target.startDrag();
}
if (targetName == 'reSizer_tl')
{
    addEventListener(Event.ENTER_FRAME, reSize_tl);
    e.target.startDrag();
}

And this to the onResizeUp function:

1
2
3
4
5
6
7
8
9
10
if (targetName == 'reSizer_tr')
{
    removeEventListener(Event.ENTER_FRAME, reSize_tr);
    e.target.stopDrag();
}
if (targetName == 'reSizer_tl')
{
    removeEventListener(Event.ENTER_FRAME, reSize_tl);
    e.target.stopDrag();
}

And we need to add these two functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
private function reSize_tr(e:Event):void
{
    if (mouseX > block.x + 20)
    {
        newWidth = reSizer_tr.x;
        blockWidth = newWidth - block.x;
        block.width = blockWidth;
    }
    if (mouseY > 0)
    {
        block.y = reSizer_tr.y;
        blockHeight = reSizer_br.y - block.y;
        block.height = blockHeight;
        }
    if (mouseX < block.x + 20)
    {
        reSizer_tr.x = block.x + 21;
    }
    if (mouseY > reSizer_br.y + 20)
    {
        reSizer_tr.y = reSizer_br.y + 21;
    }
}
private function reSize_tl(e:Event):void
{
    if (mouseX > 0)
    {
        block.x = reSizer_tl.x;
        blockWidth = reSizer_tr.x - block.x;
        block.width = blockWidth;
    }
    if (mouseY > 0)
    {
        block.y = reSizer_tl.y;
        blockHeight = reSizer_bl.y - block.y;
        block.height = blockHeight;
    }
    if (mouseX > reSizer_tr.x - 20)
    {
        reSizer_tl.x = reSizer_tr.x - 21;
    }
    if (mouseY > reSizer_bl.y - 20)
    {
        reSizer_tl.y = reSizer_bl.y - 21;
    }
}

And of course, this to the onResizeDown function:

1
2
3
4
5
6
7
8
9
10
if (targetName == 'reSizer_tr')
{
    addEventListener(Event.ENTER_FRAME, reSize_tr);
    e.target.startDrag();
}
if (targetName == 'reSizer_tl')
{
    addEventListener(Event.ENTER_FRAME, reSize_tl);
    e.target.startDrag();
}

And to the onResizeUp function:

1
2
3
4
5
6
7
8
9
10
if (targetName == 'reSizer_tr')
{
    removeEventListener(Event.ENTER_FRAME, reSize_tr);
    e.target.stopDrag();
}
if (targetName == 'reSizer_tl')
{
    removeEventListener(Event.ENTER_FRAME, reSize_tl);
    e.target.stopDrag();
}

Now add this to the addListeners function:

1
2
3
4
5
6
reSizer_tr.addEventListener(MouseEvent.MOUSE_DOWN, onResizerDown);
reSizer_tr.addEventListener(MouseEvent.MOUSE_UP, onResizerUp);
reSizer_tr.buttonMode = true;
reSizer_tl.addEventListener(MouseEvent.MOUSE_DOWN, onResizerDown);
reSizer_tl.addEventListener(MouseEvent.MOUSE_UP, onResizerUp);
reSizer_tl.buttonMode = true;

At this point all the corners should be able to resize the box, but we have one problem, they don’t move if they aren’t the one being clicked on. So we need to add this, just stick it at the bottom of the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
private function positionReSizer_bl(e:Event):void
{
    reSizer_bl.x = block.x;
    reSizer_bl.y = block.y + block.height;
}
private function positionReSizer_br(e:Event):void
{
    reSizer_br.y = block.y + block.height;
    reSizer_br.x = block.x + block.width;
}
private function positionReSizer_tl(e:Event):void
{
    reSizer_tl.x = block.x;
    reSizer_tl.y = block.y;
}
private function positionReSizer_tr(e:Event):void
{
    reSizer_tr.x = block.x + block.width;
    reSizer_tr.y = block.y;
}

To use these functions, we need to change our onResizerDown and onResizeUp functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
private function onResizerDown(e:MouseEvent):void
{
    var targetName:String = e.target.name.toString();
    if (targetName == 'reSizer_br')
    {
        addEventListener(Event.ENTER_FRAME, reSize_br);
        addEventListener(Event.ENTER_FRAME, positionReSizer_bl);
        addEventListener(Event.ENTER_FRAME, positionReSizer_tr);
        e.target.startDrag();
    }
    if (targetName == 'reSizer_bl')
    {
        addEventListener(Event.ENTER_FRAME, reSize_bl);
        addEventListener(Event.ENTER_FRAME, positionReSizer_br);
        addEventListener(Event.ENTER_FRAME, positionReSizer_tl);
        e.target.startDrag();
    }
    if (targetName == 'reSizer_tr')
    {
        addEventListener(Event.ENTER_FRAME, reSize_tr);
        addEventListener(Event.ENTER_FRAME, positionReSizer_br);
        addEventListener(Event.ENTER_FRAME, positionReSizer_tl);
        e.target.startDrag();
    }
    if (targetName == 'reSizer_tl')
    {
        addEventListener(Event.ENTER_FRAME, reSize_tl);
        addEventListener(Event.ENTER_FRAME, positionReSizer_tr);
        addEventListener(Event.ENTER_FRAME, positionReSizer_bl);
        e.target.startDrag();
    }
}

private function onResizerUp(e:MouseEvent):void
{
    var targetName:String = e.target.name.toString();
    if (targetName == 'reSizer_br')
    {
        removeEventListener(Event.ENTER_FRAME, reSize_br);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_bl);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_tr);
        e.target.stopDrag();
    }
    if (targetName == 'reSizer_bl')
    {
        removeEventListener(Event.ENTER_FRAME, reSize_bl);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_br);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_tl);
        e.target.stopDrag();
    }
    if (targetName == 'reSizer_tr')
    {
        removeEventListener(Event.ENTER_FRAME, reSize_tr);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_br);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_tl);
        e.target.stopDrag();
    }
    if (targetName == 'reSizer_tl')
    {
        removeEventListener(Event.ENTER_FRAME, reSize_tl);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_tr);
        removeEventListener(Event.ENTER_FRAME, positionReSizer_bl);
        e.target.stopDrag();
    }
}

Now the red blocks should stay attached to the corner when you’re resizing the block box. Now we have one final thing to do, make it so we can drag the black box around. It’s really simple, add this to the addListeners function:

1
2
3
block.addEventListener(MouseEvent.MOUSE_DOWN, onBlockDown);
block.addEventListener(MouseEvent.MOUSE_UP, onBlockUp);
block.buttonMode = true;

And then add there two functions at the bottom of the code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private function onBlockDown(e:MouseEvent):void
{
    e.target.startDrag();
    addEventListener(Event.ENTER_FRAME, positionReSizer_br);
    addEventListener(Event.ENTER_FRAME, positionReSizer_bl);
    addEventListener(Event.ENTER_FRAME, positionReSizer_tr);
    addEventListener(Event.ENTER_FRAME, positionReSizer_tl);
}
private function onBlockUp(e:MouseEvent):void
{
    e.target.stopDrag();
    removeEventListener(Event.ENTER_FRAME, positionReSizer_br);
    removeEventListener(Event.ENTER_FRAME, positionReSizer_bl);
    removeEventListener(Event.ENTER_FRAME, positionReSizer_tr);
    removeEventListener(Event.ENTER_FRAME, positionReSizer_tl);
}

Now you should be able to drag the box around and the red blocks will follow. Because we didn’t use any hard values in the resizing functions, we are able to make the black box dragable, which increase the usefulness of this, if you want to use it as a mask or something similar.

A simple external file loader for ActionScript 3

Monday, March 8th, 2010

One of the big mistakes that beginners make when they’re making their first Flash projects is importing all the graphics and making movieclips with tons of frames, resulting in a Flash file that is huge. The bigger the .swf, the longer it will take to load. The simplest way to fix this is to load larger files externally. Loading files is pretty easy in ActionScript 3 so I’m not going to show you how, I’ve just made this ExternalLoader class that does the job and I use it a lot at work. And to use it is the same as loading anything else in AS3. Just download the zip file and put the class wherever you save your custom classes.

Download the .zip file

To use it, you just need three lines of code:

1
2
3
4
5
import com.atomicrobot.ExternalLoader;

var image:ExternalLoader = new ExternalLoader("externalfile.blah");

addChild(image);

And you’re good to go. You can use it as many times as you need in your project and it will help keep down your file size.

The “AH-HA!” moment

Sunday, March 7th, 2010

My high school physics teacher always told his students that you shouldn’t worry if you didn’t understand what he was teaching right away, just keep at it and one day you’ll have that moment where BANG!, everything makes sense and how you see the world will change. Having that “ah-ha!” moment and having a greater understanding HTML/CSS, PHP, or ActionScript or any other web language won’t change how you see the world, but it will change your understanding of the Internet and suddenly everything you build will be more efficient and streamlined.

For me, it’s been different for everything I’ve tried to learn. For HTML/CSS I never had an moment where I just got it, I lucked out and understood what was going on right away. It’s one of those things where I have trouble talking about it and explaining it to people because I’ve never really had to think things through in a way that I would be able to communicate to others. ActionScript, on the other hand, is something I’ve had to put a lot of time into and while I found the beginning stuff not too difficult, when trying to move from simple stuff up to the more interesting and complicated, I found it a struggle sometimes to wrap my heads around some concepts. So what did I do? I kept at it. I looked at as many sources as I could to learn. I bought books by different authors, did as many tutorials as I could, because sometimes things aren’t explained in a way the I really understood. But then, every time I built something, whether for work or just for fun, I learned a little more. And along the way I had a series of small “ah-ha” moments that eventually lead to me being able to build things faster and with more efficient code.

I don’t believe you can force one of these moments but you can set yourself up to have one. A lot of the time when I figure things out, I have them when I’m no where near a computer. I’ll have them when I’m walking to work, thinking about what I’m working on and what I’m going to try to do that day. Sometimes I do a tutorial and one little part of it helps me realize the solution to something that’s been bugging me for weeks.

But beware, that “ah-ha” moment might never come. Sometimes your brain just isn’t wired to figure some stuff out. One thing I really wanted to do, was be able to make great digital art with Photoshop, but after watching a lot of videos and doing a bunch of tutorials, I found myself being constantly amazed by creativity when using some of the filters in Photoshop. No matter how much I tried, I just can’t think like that. And there’s nothing wrong with that, I can do a lot of stuff with Photoshop, but I’ll never be able to make some of the things I wish I could. The key is to find something that you both enjoy working with and are able to do, there’s no sense in beating your head against a brick wall.

So what’s the point of all this? Keep at it and eventually you’ll figure it out, something will click and you’ll look back at your old stuff and wonder what the hell you were thinking! Trust me, that’s actually a good thing.

Using Tweens in ActionScript 3

Wednesday, 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.

3 Great Books to Help You Learn ActionScript 3

Monday, February 15th, 2010

The great thing about the Flash community is all the sharing. You can pretty much find the solution to any problem or question you have. There’s tons of blogs and forums out there that are full of information on Flash and ActionScript. And you can learn a lot from these resources, but, for me, I’ve found it easier and sometimes a lot more convenient to have a book or two you have look through. Since Flash was a class I took at school, I actually started learning about it from a book before I ever realized there was all this information out on the web and I think that the best way to get into Flash and ActionScript is to start with a book and then use online resources once you get a basic understanding.

1. Learning ActionScript 3.0: A Beginner’s Guide by Rich Shupe and Zevan Rosser

Learning ActionScript 3.0 is a great book for someone just getting started with AS, someone migrating from AS2 to AS3 and even for an experienced Flash designer. It has an easy reading style moves you along at a quick pace. There’s also a great companion website at learningactionscript3.com. I can’t recommend this for an experienced developer because it covers just the basics of ActionScript 3 but it wouldn’t be a bad book to use as a refresher. While it’s a great book to for an introduction to AS3 and Flash, this book isn’t set up to be used as a reference text, it’s really just what it says it is, an introduction to ActionScript. I wish that this book had been out when I was in school, it would have been perfect for my switch to AS3.

2. Essential ActionScript 3.0 by Colin Moock

As the title says, this is pretty much the essential book for any serious ActionScript developer. This book has 946 pages and, from what I can tell, covers every aspect of ActionScript 3. While a beginner could be in over their head, an experienced programmer will find this book to be a great introduction ActionScript 3. Colin Moock has a huge rep in the Flash community and is a great teacher. This book, along with the companion Lost ActionScript Weekend dvds, is a must have for any serious developer or designer the wants to take Flash to the next level.

3. The ActionScript 3.0 Quick Reference Guide by David Stiller, Rich Shupe, Jen deHaan and Darren Richardson

This book is a little different than the other 2 on the list, it’s not really a step by step how to of using Flash and ActionScript. A bit newer than the other books, this one includes info on how to use Flash CS4 and migration from AS2 to AS3. About half the book is a How-To section, including topics like How Do I Work With Events and How Do I Work With XML. This shouldn’t be your first book when trying to learning AS3 but beside the other two it works really well, especially if you need to learn how to do something that you haven’t done before.

There’s a bunch of books out there, but these 3 are the ones that I’ve found helped me the most.

Step 5 in Building a Shooter Game in AS3

Wednesday, February 10th, 2010

On to the final step in making our shooter! You can go back and check Step 1, Step 2, Step 3 and Step 4 if you missed something. In this step, we’re going to add a score and set up our rocket so it can be hit by the enemy ships. This one’s going to be pretty simple, the point of this whole tutorial was to show the basics of building a game in AS3. If you want to take it farther, it won’t be that difficult and will be a great learning experience.

The first thing we are going to do is use the Text Tool (T) to add a dynamic text block to the stage. I put mine in the bottom left, but you can put it anywhere. Make sure that it’s set to dynamic text, not static or input and give it an instance name of scoreTxt. Because it’s dynamic we can change the contents with ActionScript and it’s only going to take a few lines of code to do this. First, we need to add this to the bottom of the other variables:

1
2
//Sets the variable score as an integer
var score:int = 0;

Next, in the rocketMovement function, right before the closing bracket, add:

1
scoreTxt.text = "Score: " + score;

This sets the text inside our scoreTxt textfield with the text() method. We’re telling it to display the word Score plus our variable score, whose value we will assign next in our Enemy class. The reason at we are putting this line of code in the rocketMovement function is because we are listening for any changes to score every frame. We could create a new function just to update the score, but since rocketMovement is doing what we want anyway, we can just add it in there.

Now in the Enemy.as file we just have to had one little line of code. Put this in the moveEnemy function:

1
_root.score += 5;

Now, when the enemy ship is destroyed, the game will add 5 to the score.

The easiest way I’ve found to end the game is to use a Boolean. In the main code, I created a variable called dead, typed it to Boolean and set it to false:

1
var dead:Boolean = false;

Now go into the Enemy.as file and add this code to moveEnemy function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//tests to see if the enemy ship has hit the rocket movieclip
if (this.hitTestObject(_root.rocket))
{
    //if it has, dead is set to true
    _root.dead = true;
}
//check to see if dead equals true    
if (_root.dead == true)
{
    //remove listener and the ship from the stage
    removeEventListener(Event.ENTER_FRAME, moveEnemy);
    _root.removeChild(this);
    //add the game over text to the stage
    var gameOver:GameOver = new GameOver();
    _root.addChild(gameOver);
    gameOver.x = 125;
    gameOver.y = 100;
    //move the rocket off the stage
     _root.rocket.x = -100;
     _root.rocket.y = -100;
}

I’ve created a moveclip that says Game Over, I named it gameOver and checked the Export for ActionScript box. When an enemy ship hits our rocket, the game will remove all the ships from the stage, move our rocket off of it and add the Game Over movieclip. The reason we are moving the rocket movieclip off the stage instead of removing it is because we put it on the stage in our .fla, if we had added it with addChild() we could remove it easier, but it’s not that big of a deal.

That’s it! Now you should have the basics of a shooter game that you can build on, adding lives and more than one kind of enemy shouldn’t be too hard. I hoped this helped and now I have to figure out what to build next.

Step 4 in Building a Shooter Game in AS3

Friday, January 29th, 2010

So far, we’ve made a ship move, shoot lasers and make enemies move around. Now we are going to make the lasers hit the enemies.

This was probably the hardest part of my AS2 game to switch over to AS3, because all the code in AS2 was in the actual .fla. Since the code for both the laser and the enemies were actually on the stage, it wasn’t too hard to make them interact. But since we are making this is in AS3 and the code of the laser and enemy ships are in their own AS files, we have to figure out a way to have the enemy ship code know where the lasers are on the stage. The easiest way to do this is to just add a movie clip to the stage and put the lasers inside it. This way, we can keep track of where the lasers are and how many there are. So, the first thing we have to do is add this code to the top of the main code in your Flash file:

1
2
var laserHolder:MovieClip = new MovieClip();
addChild(laserHolder);

And down where the laser is added to the stage, change it to this:

1
laserHolder.addChild(newLaser);

Alright, that’s all we are going to change in the main .fla. Next, we have one thing to add to Enemy.as, put this in the moveEnemy function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//Make a loop that contains the number of lasers on the stage
for (var i:int = 0; i < _root.laserHolder.numChildren; i++)
{
    //add a new movieclip for each laser on the stage
    var laserTarget:MovieClip = _root.laserHolder.getChildAt(i);
    //check if any of the lasers has hit this enemy
    if (hitTestObject(laserTarget))
    {
        //if it has, then remove this enemy ship from the stage and remove all the listeners
        removeEventListener(Event.ENTER_FRAME, moveEnemy);
        _root.removeChild(this);
        //this removes the laser
        _root.laserHolder.removeChild(laserTarget);
        //this removes the laser's listeners
        laserTarget.removeListeners();
    }
}

I commented the code because it’s easier than explaining it here. We just have to make one more change or we’ll get an error. If we left it like this, the laserTaget.removeListeners() line would give us an error. The reason for this is pretty simple, we are trying to access a function in the Laser.as file from the Enemy.as file and that function, removeListeners() is a private function. In order for Enemy.as to access this function, we just need to switch it to public. So in Laser.as, change:

1
private function removeListeners():void

to:

1
public function removeListeners():void

That’s it, now we can shoot the enemies!

Some Flash stuff I came across

Monday, January 25th, 2010

I came across a link on Twitter for FlashMoto.com, Top Flash Trends for 2010. There’s nothing crazy here, Augmented Reality and Adobe AIR 2.0, stuff like that. But #6 caught me off guard a bit, The Mass Creation of Flash Content Management Systems. Whaa?? Flash CMS? In all the reading I’ve done, I can’t recall reading anything about Flash CMS becoming a big thing. I’ve never been to FlashMoto before, so I went to their home page and, surprise, surprise, they sell a Flash CMS. I’m not ripping on their business or anything, but that’s just kinda funny to me.

In a post that’s not selling you anything, Warm Forest has a nice post called 11 Myths About Flash That Won’t Die. Stuff like You can’t select and copy text on Flash sites and Flash isn’t supported on mobile devices are stuff I hear all the time. It’s a good post to show to your boss at work who never lets you build anything in Flash and ActionScript. Unless, like me, you have 6 months of being annoying to make them see it your way!

Finally, I don’t know why but some software developers just have a hate on for Flash. I’m not saying Flash is perfect and I’m not thrilled that it’s proprietary, but it let’s you do some sweet stuff and it looks and works the same no matter what browser it’s in. But, this guy, OSS Guy, has declared Flash dead and says all Flash developers should stop now and start working in HTML5/CSS3, which of course, means you’re now cutting out anyone that uses any version of IE and considering how well Microsoft has been doing at implementing CSS as it is now, I’m sure they’re going to be right on the bandwagon for CSS3. And it seems to me, a lot of software developers forget that one of the main uses of Flash is animation and if Flash is dead, then Teletoon is screwed when it comes to making their own shows! Plus, does anyone have any tutorials on how I can make HTML5 games? I’d really like to remake Frogger using it.

Animate the GlowFilter in AS3

Friday, January 22nd, 2010

Sometimes when it comes to Flash and ActionScript, it’s the little things that can help out. I had an idea for something that would use the glow filter when you hovered over certain objects. The first way to do this that popped into my head was to create a movieclip in Flash, add a glow filter to it using the Properties panel and then tweening the glow’s strength from 0% to 250% to get the effect I wanted. The ActionScript would be pretty simple, MOUSE_OVER has a gotoAndPlay frame 2. But there are a few issues with this. First, when you hover over the movieclip, our glow will go from zero to full strength no matter what, even if the cursor leaves it while it’s halfway there. Second, making any adjustments means going into the movieclip and adjusting the filter on 2 or more keyframes. The first issue we could fix with something like Tweener or Gtween, but that doesn’t solve the second issue and we have to learn how to use one of these tweening libraries. The easiest way to solve both of these issues is to add and control our filter with built in ActionScript features.

I want to keep this short, so I’m not going to go through what every filter does and what each filter’s properties are. You can learn all that in this great post at Republic of Code.

We’ll just give a movieclip that’s on the stage a glow filter and then we’ll animate it. So, put something on the stage, it can be a box or anything you want. I made a green Atari style robot in Illustrator and brought into Flash as a png. My movieclip’s instance name is robot but you can call yours whatever you want. Make a new layer and put this code on that layer:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//We have to import the filters so we can use them
import flash.filters.*;

//This creates a new GlowFilter that we can then assign to a movieclip on the stage
var robotGlow:GlowFilter = new GlowFilter();
//The color of the GlowFilter
robotGlow.color = 0x138613;
//The size of the filter on the x-axis
robotGlow.blurX = 50;
//The size of the filter on the y-axis, these don't have to be the same
robotGlow.blurY = 50;
//Setting the alpha of our filter to zero to start off with
robotGlow.alpha = 0;
//Assigning the GlowFilter to the robot movieclip
robot.filters = [robotGlow];
//This will tell our filter when to turn on and off
var glow:Boolean = false;

//Our listeners
robot.addEventListener(MouseEvent.MOUSE_OVER, addGlow);
robot.addEventListener(MouseEvent.MOUSE_OUT, removeGlow);
addEventListener(Event.ENTER_FRAME, increaseGlow);

//This function sets glow to true which turns on the glow when the mouse cursor is over our movieclip
function addGlow(e:MouseEvent):void
{
    glow = true;
}

//This turns off the glow when the mouse cursor leaves the movieclip
function removeGlow(e:MouseEvent):void
{
    glow = false;    
}

//This checks the status of glow and turns on and off our glow
function increaseGlow(e:Event):void
{
    if(glow == true)
    {
        //If glow = true, then it will increase the alpha of robotGlow by 0.02 each frame.
        //This number can be changed to anything between 0 and 1 depending on how fast
        //you want the glow to appear
        robotGlow.alpha = robotGlow.alpha + 0.02;
    }
    else if(glow == false)
    {
        //If glow is false, then it will decrease the alpha by 0.02
        robotGlow.alpha = robotGlow.alpha - 0.02;
    }
    //Assigns the glow filter with the new alpha to robot
    robot.filters = [robotGlow];
}

Using this code we will get this:

This code will be perfect if you want to add glow or another filter to Flash site’s navigation or something similar. Its just under 40 lines, so it’s pretty simple and easy to use.

Step 3 in Building a Shooter Game in AS3

Tuesday, January 19th, 2010

In step 1, we made our ship move around the screen and in step 2, we made it so it can fire lasers. Now we have to give it something to shoot at.

This is similar to what we did with the lasers in step 2 but to get the enemies to appear on the stage, we just need to do a few things, declare a variable that will set the number of enemies and add a for loop to our code.

Make your ship in your .fla, convert it to a movieclip, call it Enemy and Export it For ActionScript, it should say Enemy there as well. Delete the ship from the stage, you just need it to be in your library.

Now add this to your list of variables in the code you have in your .fla:

1
var nrEnemies = 6;

and then at the bottom of your code, add this:

1
2
3
4
5
for (var i=0; i<nrEnemies; i++)
{
    var enemy:Enemy = new Enemy()
    addChild(enemy);
}

Now, just like with the lasers, we have to make a new ActionScript file to control our enemies, File > New > New ActionScript File. Save it in the same folder as your .fla and the Laser.as file, call it Enemy.

Our package is going to look like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package
{
    import flash.display.MovieClip;
    import flash.events.Event;
   
    public class Enemy extends MovieClip
    {

        public function Enemy():void
        {
           
        }
    }
}

Pretty simple, we’re importing MovieClip and Event because those are the only two classes we’re using for our Enemy class. Now let’s fill this out. We have four variables, add them after the class statement but before the function:

1
2
3
4
private var _root:Object;
private var enemySpeed:Number;
private var timer:Number = 0;
private var dir:Number;

Just like with our Laser class, we have the variable _root to bring in our stage info. Next we set up the variable for the speed our enemy ships are going to travel, we aren’t assigning it a number here because we’re going to set it up so the number is random for each enemy. timer is going to be used to change the direction of our ships so they they aren’t just flying straight across the stage. And dir is the direction that our enemy ship is going.

Inside the Enemy function add:

1
2
addEventListener(Event.ADDED, addClass);
addEventListener(Event.ENTER_FRAME, moveEnemy);

Pretty much the same as our Laser class, we’ll run the addClass function when the enemy ship is added to the main stage and then every frame we’ll run the moveEnemy function. And since we’ve added some event listeners, we better write the functions. First, we’ll write the addClass function.

1
2
3
4
5
private function addClass(e:Event):void
{
    _root = MovieClip(root);
    addShip();
}

Inside our addClass function, we have the same line as in the Laser class, _root = MovieClip(root);. But we also have addShip();. This triggers an addShip function instead of having another event listener. Add the function right after addClass.

1
2
3
4
5
6
private function addShip():void
{
    this.x = 600;
    this.y = Math.random() * 400;
    enemySpeed = Math.ceil(Math.random() * 5);
}

What the addShip function is doing is assign the enemy ship’s position, x is always 600, off the stage and the y is random. We multiply the number Math.random() generates by 400 so that the
enemy will appear anywhere between 0 and 400. And we finally assign a value to our enemySpeed variable. Math.ceil rounds the number off and we generate a speed between 1 and 5. Next we’ll add the moveEnemy function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private function moveEnemy(e:Event):void
{
    this.x -= enemySpeed;
           
    if (this.x < 0 - this.width)
    {
        addShip();
    }
    if (timer >= 25)
    {
        dir = Math.ceil(Math.random() * 2);
        timer = 0;
    }
    if (dir == 1) {
        this.y -= 1;
    }
    else if (dir == 2) {
        this.y += 1;
    }
    timer ++;
}

This is where we’ll control the movement of our enemy ship. We assign the subtract enemySpeed from the x position of our enemy ship it have it move right to left across the stage. Next we check to see if the enemy ship’s x position is less than zero. If it is, we run the addShip function again, which will move the enemy ship back to the right side of the stage so it can attack again. Then we’re checking to see if timer’s value is over 25, if it is, we assign dir a value of either 1 or 2 and reset timer back to zero. Depending on the value of dir, the enemy ship will either move up or down at the rate of 1 pixel per frame. Finally we add one to timer with timer++ at the end of the function. The two if statements at the end are what will make our enemy ships travel up or down but they won’t constantly switch back in forth, because the value of dir is random, it could be 1 four times in a row or it could constantly switch. This will give our enemies a little more life to them and make the game more interesting.

Now you should have something like this:

Here’s the complete code for Enemy.as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package
{
    import flash.display.MovieClip;
    import flash.events.Event;
   
    public class Enemy extends MovieClip
    {
        private var _root:Object;
        private var enemySpeed:Number;
        private var timer:Number = 0;
        private var dir:Number;
       
        public function Enemy():void
        {
            addEventListener(Event.ADDED, addClass);
            addEventListener(Event.ENTER_FRAME, moveEnemy);
        }
       
        private function addClass(e:Event):void
        {
            _root = MovieClip(root);
            addShip();
        }
       
        private function addShip():void
        {
            this.x = 600;
            this.y = Math.random() * 400;
            enemySpeed = Math.ceil(Math.random() * 5);
        }
       
        private function moveEnemy(e:Event):void
        {
            this.x -= enemySpeed;
           
            if (this.x < 0 - this.width)
            {
                addShip();
            }
            if (timer >= 25)
            {
                dir = Math.ceil(Math.random() * 2);
                timer = 0;
            }
            if (dir == 1) {
                this.y -= 1;
            }
            else if (dir == 2) {
                this.y += 1;
            }
            timer ++;
        }
    }
}