The Wayback Machine - https://web.archive.org/web/20130518193240/http://active.tutsplus.com:80/tutorials/actionscript/quick-tip-how-to-use-a-document-class-in-flash/
Quick Tip: How to Use a Document Class in Flash
basix

How to Use a Document Class in Flash

Tutorial Details
  • Difficulty: Basix

We’re making some changes at Activetuts+. From now on, our tutorials will be using class-based code, instead of timeline code, wherever possible. This Quick Tip explains what you’ll need to know.


Why Use Class Files?

I’ll admit it – sometimes, coding entirely on the timeline is useful. It’s a quick way to test out an effect, and the easiest way to sync actions to specific frames of an animation.

But for any project that relies more on code than on animation, there are serious disadvantages. All your ActionScript is trapped inside the FLA file; you can’t split the programming between different developers, you have to copy and paste code if you want to re-use it, and you’re forced to use Flash’s Actions Panel.

Using class files sets your code free. And it’s really no harder than coding on the timeline; it just involves a little more setup. I’ll walk you through creating a Flash project that uses classes, then break down a class file in detail.

(Part of the reason we’re switching to classes is to make it easier for AS3 developers that don’t use Flash itself to follow our tutorials. If you’re one of them, I expect you’re used to dealing with classes already, but you can always read this Quick Tip as a refresher – just ignore the bits about Flash!)


Step 1: Create a FLA

I’m sure you already know how to do this. Open Flash and click File > New … Flash File (ActionScript 3.0). Save it wherever you like. I’ve called mine Example.fla, but it doesn’t matter what name you choose.


Step 2: Create an ActionScript File

Click File > New … ActionScript File. Save this as Main.as in the same folder as your FLA.

This file is where we’re going to put the code that powers the FLA itself, but how will Flash know how to find it?


Step 3: Link the FLA to the AS File

You may have dozens of AS files in the same folder as the FLA, so Flash won’t want to guess which one to use. We’ll have to tell it.

Switch to the Selection tool (Shortcut: V), then make sure you have nothing selected (hit Ctrl-Shift-A). Open the Properties panel (Window > Properties).

If you’re using Flash CS3, it’ll look like this:

Flash CS3 Properties Panel

Enter Main in the box labeled “Document class” – that’s to match the name of your ActionScript file, minus the “.as” file extension..

If you’re using Flash CS4, it’ll look like this:

Flash CS4 Properties Panel

In this case, you’ll need to enter Main in the box labeled “Class”. For some reason, Adobe dropped the “Document” bit.


Step 4: (Optional) Reorganize your Folder Structure

You don’t have to keep all your files in the same directory. Check out this Quick Tip screencast if you’d like to know how to move things around.


Step 5: Write your Document Class

Open your Main.as file and paste the following code:

package
{
	import flash.display.MovieClip;
	public class Main extends MovieClip
	{
		public function Main()
		{
			
		}
	}
}

This is a basic empty document class. It’s the smallest amount of code we can write that will actually run. Let me break it down:

The package keyword tells Flash that all of the code between its curly braces is part of a single group.

The package keyword tells Flash that all of the code between its curly braces is part of a single group.

The class keyword groups functions and variables together.

Writing class Main also groups code together, but in a different way. Classes contain functions and variables; packages contain classes and import statements.

Note: you have to give your class the same name as the AS file: Main.

What about public? Well, that just means that other classes in your code will be able to see this class.

We want our class to extend the functionality of a regular MovieClip - hence, 'class Main extends MovieClip'.

This class Main is going to power our FLA. By default, our FLA is a movie clip (it has a timeline).

We want Main to be able to do everything that a movie clip can do, plus more based on the code that we write. In other words, we want to extend the functionality of a regular MovieClip.

(Sometimes, we might not need to do any animation on the stage’s main timeline; in this case, we don’t need to extend MovieClip, and we can just extend Sprite instead. MovieClip itself extends Sprite, but adds extra features for animation, like the nextFrame() function. So if you’re not sure whether you should extend MovieClip or Sprite, go for MovieClip — it’s safer!)

The 'import' line tells Flash where to find the actual MovieClip so that we can extend it.

MovieClip is itself a class.

Flash doesn’t automatically keep track of where all its class files are stored; in order for our extends MovieClip code to work, we need to tell Flash where to find the MovieClip class. That’s what the import line does.

Import statements always go inside the package and outside the class, at the top.

Every class contains a function with the same name as the class. The code inside it is run when an object of this type of class is created - in our case, when the SWF is loaded.

Every class contains a function with the same name as the class. It’s called the constructor function.

All the code inside this function is run when an object of this type of class is created – in our case, code between these curly braces will be run when the SWF is loaded.

Don’t worry if you feel you don’t quite grasp all of this yet. Once you start actually using classes and writing your own, it’ll all snap into place.


Step 6: Make it do Something

As I said in Step 5, the constructor function contains the very first code to be run when your SWF is loaded. So let’s put something in there to make sure everything’s working:

package
{
	import flash.display.MovieClip;
	public class Main extends MovieClip
	{
		public function Main()
		{
			trace( "Yep, it's working" );
		}
	}
}

Line 8 is the only new one there. Test your SWF in the usual way (Control > Test Movie). If all’s well, you should see “Yep, it’s working” pop up in the Output panel. If not…

  • Have you saved the change you made to Main.as?
  • Is your FLA’s Document Class set to Main?
  • Are you definitely testing the Example.fla movie?

If none of these questions help, please post a comment.


Step 7: Try Something a Little More Complex

Try replacing your Main.as code with this:

package
{
	import flash.display.MovieClip;
	public class Main extends MovieClip
	{
		public function Main()
		{
			var greeting:String = "Hello";
			trace( greeting );
		}
	}
}

Simple, right? We’ve just created a new String variable inside the constructor function. Now let’s add a new function:

package
{
	import flash.display.MovieClip;
	public class Main extends MovieClip
	{
		public function Main()
		{
			var greeting:String = "Hello";
			changeGreetingToFrench();
			trace( greeting );
		}
		
		public function changeGreetingToFrench():void
		{
			greeting = "Bonjour";
		}
	}
}

There are a few things to note here.

Firstly, the new function goes inside the class, and after the constructor – by convention, the constructor is the first function in the class.

Secondly, the new function is public; when coding inside a class (and not on the timeline) it’s good practice to put “public” (or “private” or “protected”, but I’ll leave those for another post) at the start of the line that defines the function. It’s just a way of letting other classes know whether or not they can access it.

Thirdly, the new function’s definition ends with :void. This just means it doesn’t return a value. Constructor functions don’t need the :void because they can’t return a value.

If you test this movie, you’ll get an error message:

Main.as, Line 15: 1120: Access of undefined property greeting.

When you create a variable inside a function, it can’t be accessed by other functions. If you want every function in the class to be able to access the variable, you need to declare it inside the class but outside all of the functions:

package
{
	import flash.display.MovieClip;
	public class Main extends MovieClip
	{
		public var greeting:String = "Hello";
		
		public function Main()
		{
			changeGreetingToFrench();
			trace( greeting );
		}
		
		public function changeGreetingToFrench():void
		{
			greeting = "Bonjour";
		}
	}
}

Just as with functions, if you declare a variable outside of a function, you need to start it with “public” (or “private” or “protected”). Unlike functions, variables should be defined above the constructor.

Test your movie now and you should finally get a nice greeting in French. How useful!


Wrapping Up

So, this is not exactly an exciting result, but hopefully you now feel able to follow tutorials that don’t code on the timeline.

I really want to make sure everyone understands how to use a document class, so please, if any of this was unclear, post a note in the comments. Once we’ve sorted out the confusion, I’ll edit the Quick Tip to make it easier for the next person to understand. Thanks :)

  • Pingback: Quick Tip: Conjure up a Jazzy Mouse Cursor Trail | Flash Video Traning Source

  • Pingback: Quick Tip: Call jQuery Inside AS3 Using jotAQuery | Flash Video Traning Source

  • http://www.pigandcow.com Scott

    First of all, great tutorial. I was scratching my head as to how to get code to execute when a movie starts without having to add anything to the timeline.

    Here’s an interesting problem I you might have some insight on: I’m writing a library that sits on top of a movie to grab up events and send information about them to a server. Ideally I’d like to make an .swc that could just be compiled into the .FLA so that when the movie starts, an object of class “Vacuum” would be instantiated and start sucking up events.

    If I added something into the movie’s document class to instantiate the object (or made Vacuum the document class itself) then this would work fine. The problem is that I’ll be giving this .swc to designers who aren’t going to know how to do either of those things. Is there a way to get code to execute when a movie loads, without a) dragging a symbol linked to “Vacuum” to the timeline (dirty!) b) adding code to instantiate a “Vacuum” object into the document class or c) making “Vacuum” the document class?

    Thanks!

    Scott

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      Sorry, Scott, I missed your comment. You could try telling the user to make sure their document class extends Vacuum?

  • nick

    hey there,i downloaded your source file for the pan zoom tutorial,and opened it up in Flash CS4,but nothing happens? tried putting supporting document classes in different directory,nothing happens :-( please help…

  • puggsoy

    This is really simple, clear and explains Document Classes well. When migrating from AS2 to AS3 I saw all these tutorials with classes instead of timeline code, which was real weird. Even without tutorials I can see the advantages of Document Classes instead of timeline code.

    Thanks for making this.

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      Thanks very much :) Glad you found it useful!

  • Pingback: Adjust the Color Properties of an Image Using ActionScript 3 | All of Cyber

  • Pingback: Blow an Image Away with a Custom Wind Effect | All of Cyber

  • stev

    Hi! Great tutorial :D It’s a really ice breaker :)

    But what if I have multiple classes? I know you can’t put more than one class inside a .as file.

    For example I have:

    A.as, B.as and C.as in folder “letters”, each with their own class and all of them begin with package com.adobe.letters {….} , so they are in the same package and A, B and C will be able to communicate between them.

    And I also have:

    1.as, 2.as and 3.as, each with their own class and in same package, com.adobe.numbers {….}, so they communicate between them but not with A,B or C.

    And inside flash, on the timeline, I add
    “import com.adobe.letters.A;
    import com.adobe.numbers.1;”

    In Publish Settings I added in classpath a path to each package. Firstly the letters package and then the numbers package.

    How can I make this work, because now, the A class code works, but the 1 class code is not working.

    Thanks.

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      Hey Stev! Have you read my article about using external libraries in AS3? It explains a little about classpaths and imports, so it might help you out.

  • http://active.tutsplus.com/tutorials/actionscript/quick-tip-how-to-use-a-document-class-in-flash/ tarun thakur

    great… but i m bigener so i fully ried to understan it… and thks.

  • http://vxcriss.com vxcriss

    Hey thanks for the tutorial, I had a hard time figuring out how to split up the script from the main fla file. Did too much in-fla-coding over time, it’s hard for me to get organized now :)

  • http://craigehutchison.com Craig

    Hi, This was an awesome tutorial, thank you, I am just getting into doing things this way instead of working on the timeline. I have a question about working with multiple movieclips. I want to use classes to work with multiple movieclips, the instance names would be card1, card2, card3, etc.
    Here is what I have so far, my fla is linked to main.as which is below:

    package com.lcpractice.basics
    {
    	//list of our imports these are classes we need in order to
    	//run our application.
    	import flash.events.MouseEvent;
    	import flash.display.MovieClip;
    	import flash.display.Stage;
    	
     
    	//our Engine class it extends MovieClip
    	public class Main extends MovieClip
    	{
     		
    		//our constructor function. This runs when an object of
    		//the class is created
    		public function Main()
    		{
    			var test:Test = new Test();
    			test.talk();
    			var card1:Cards = new Cards();
    			addChild(card1);
    			card1.test = test;
    			card1.talkToTest;
    				
    	
    		}
    		
    		
    }//public class cards
     
    }//package
    
    **** then the class Cards that I try to use looks like this:
    /our package... simply put, the directory structure to this file
    package com.lcpractice.basics
    {
    	//list of our imports these are classes we need in order to
    	//run our application.
    	import flash.events.MouseEvent;
    	import flash.display.MovieClip;
    	
    	
     
    	//our Engine class it extends MovieClip
    	public class Cards extends MovieClip
    	{
    		private var_test:Test;
     		
    		//our constructor function. This runs when an object of
    		//the class is created
    		public function Cards()
    		{
    			//var test:Test = new Test();
    			//test.talk();
    			//var card1:Cards = new Cards();
    			buttonMode = true;
    			addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
    			addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    			
    			
    //			addEventListener(MouseEvent.MOUSE_DOWN,Card1downHandler);			
    		}
    		
    		private function mouseDownHandler(event:MouseEvent):void
    		{
    			startDrag();
    	
    			
    		}
    		private function mouseUpHandler(event:MouseEvent):void
    		{
    			stopDrag();
    	
    			
    		}
    		public function set test(value:Test):void{
    			_test = value;
    		}
    		public function talkToTest():void{
    			_test.talk();
    		}
    		
    }//public class cards
     
    }//package
    

    **** I get no errors and the output window shows the trace statements but for some reason the moveclip shows up and cannot be dragged around, am I not accessing it correctly?? Thanks for any help you can give… Thanks again

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      Have you tried adding the mouse event listeners to the card inside your Main class, rather than inside your Card class?

      • Craig

        Hi Michael,
        Thanks a lot, that worked.. also, I had to have it linked through the library. now if I want to create a number of cards that will interact through movement and hittests, should I do it all in the Main class in different functions. And is there a way to access which movieclip I have grabbing programmatically, say if a user clicks on card1, can I access the instance name card1 to compare it with the others. Thanks so much for your help. This is a real learning curve

  • Jalal

    Thank you! it was awesome!

  • http://you-and-me.co.uk eric

    If you have object on the stage that have classes linked to them and have main doc class for the main swf, why does the main doc class run after all the object classes, surely this counter intuitive. The main doc class should run first as it may have all the global vars and functions for house keeping, management and etc and initiates other states in other classes.

    My swf has only one frame, so ordering that way wont work, so how to have a main class run first in this situation.

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      That surprises me. Hmm. Maybe you could try the preloading method explained in this tutorial?

  • Mookiie

    Thank you so much for this! Ive been in a course that uses this for the last two months and you have managed to clearly explain more here then they have managed to do in the last four lectures! thank you again :D

  • http://rowel.byethost32.com gorel

    what a great tutorial!!! Thank you very much for sharing!! It’s really helpful.

  • mohammed shiraz

    good one it really helped since u kept it simple!

  • Masarwa Shhadi

    This is the Greatest Explain of Classes and Packages, thank you so much brother!

  • Pingback: AS3快速技巧:处理事件流 | Flash开发者大会

  • Ciaran

    Thanks so much for FINALLY allowing me some success in setting up a flash project!

  • pepper

    Hi
    I’m a newbie and have started watching the tuts -great videos, by the way.
    However, im using cs5 & have got this message : Package cannot be nested on my frame 1, line 2 – & the code that im using is basically copied from here:
    package
    {
    import flash.display.MovieClip;
    public class Main extends MovieClip
    {
    public function Main()
    {
    trace(“Yep, it’s working”);
    }
    }

    }

    can anyone help & explain why?
    have i missed anything?
    & when I tried to insert the Main in the ‘class-under properties-’ – I got this message:
    A definition of the document class could not be found in the classpath, one will be automat. created in the swf file…

    any help would be much aprpeciated
    thank you

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      Hey Pepper,

      Looks like perhaps you’re using timeline code instead of a separate class file. Is that correct?

  • Pingback: Flash documents | Swankyaffairs

  • Ali Kale

    Excellent tutorial. I would like to move frame based as3 to class format. I need more tutorials that control movie clips and buttons.

  • Pingback: Creating a Virtual Joystick for Touch Devices : Technology – World Begins Here – Games, Movies, Apps, Tutorials And More – Visit Guglex.com

  • http://in.linkedin.com/pub/ankit-kumar/31/916/751 Ankit Kumar

    Nice Tutorial…. Good way to teach……

    Thanks a lot to posting this this tutorial….

  • http://jqueryextensions.blogspot.com hitesh

    thanks, nicely written

  • http://www.ksk-resume.co.nr kannan

    very simple explanation and easy understood ! Great !!

  • http://ishpreet2000.hpage.com/ Ishpreet

    How can we write functions that are done when an event in the code in the timeline happens-
    Code in the timeline-
    myButton_btn.addEventListener(MouseEvent.CLICK, myFunction);
    and want to tell what my function is inside the class.

    • http://michaeljameswilliams.com/ Michael James Williams
      Author

      I’m a little confused – why does that code have to be in the timeline?

      • http://ishpreet2000.hpage.com/ Ishpreet

        Please just tell me how can I make functions in the class that only do what they are told to when an event (eg. MouseEvent.CLICK, etc) happens, but not happen always. I’m creating a game on my own and functions in it have very long definitions, so, in order to not get confused i’m writing my functions in classes, if we can do such a thing then that would help me. I want flash to do a function only when the user presses the left key, it aint happening, please help.

      • http://michaeljameswilliams.com/ Michael James Williams
        Author

        That’s a little outside the scope of this Quick Tip – have a look at our AS3 101 series instead :) http://active.tutsplus.com/sessions/as3-101/

  • CJBannister

    For some reason I’ve really struggled getting my head around the document class, it’s just so scary to look at, at first. This post is Scooby Doo style, it took the mask off the monster and it turns out it was just the guy in charge of the water slide.

  • amar

    thank u sir i understand u r code perfectly

  • raju

    thanku sir,its very clear

  • Jurgen

    Thanks! Clear talk!

  • yallum

    is verly good totorial me like this to friends

  • Lional

    I am Lional. I like this tutorial very useful and simple.

  • Ken

    Very nice Tutorial. Thanks! I am a beginner and tyring to understand document class. Following your steps, everything worked just fine. but when I test the movie, I can only see “Bonjour” showing in Output area but not in flash player and html window . Am I missing some thing?