Bryan Grezeszak does Flash AS 3.0 development at Elemental in Troy MI. He is a thorough expert of both ActionScript 2.0 and 3.0, and is more than willing to answer any questions you may have.
For most purposes, the word developer means coder. Flash
is different: 90% of Flash Developers are actually graphics/animation
experts that only use light ActionScript 2.0. There is no shame in
this. Flash is an extremely broad program, and needs experts in each of
it's many areas. These animation gurus got by with an basic knowledge
of AS 2.0 or 1.0, and did that only because is was a fairly simple
language to get the basics of, and it afforded them some interactivity.
Then came the beast. ActionScript 3.0 is a different kind of language,
a language that involves more than a little memorization as you go. AS
3.0 was built from the ground up for coders.
There
are lots of 3.0 tutorials on the web for the major advanced concepts
that have changed, but the basics are being overlooked. I
have a solution: AS 3.0 Coming From 2.0. We will go over scripts
commonly used by animators and light flash programmers in AS 2.0, then
show how, why, when and where to do the equivalent in 3.0. If you are
an AS 2.0 expert, some of this will also help you, you'll just have to
put up with all my explaining of the concepts, which you'll already
know.
REMEMBER! The help section is your friend! I'm an expert coder that
builds large and complex programs, but even I have the help section on
a tab right beside my actions panel. It's not like Word, where help is
where you go when you don't know what your doing, it's more like a
complete AS dictionary at your fingertips.
Lesson 1: Paths
Most
2.0 programmers that begin learning 3.0 run into this issue first:
_parent (now just parent) and _root (now just root) don't work as
planned. Make a movie clip, and inside it, put:
// this is inside a movie clip, trying to call to the main timeline
parent.gotoAndStop(2);
You'll get an
compiler error, it'll scream error codes at you, and it just plain
won't work. Many believe that this is the end of it, and parent just
doesn't work worth crap any more. But I have a solution that doesn't
involve complex event dispatching.
AS 3.0 is picky
about moving up paths. It uses class inheritance instead of the old
prototype inheritance. It was designed to dispatch events, use
listeners, pass variable that point to objects, all that stuff that us
coders drool about, and make animators prefer to gouge their eyes out
with a spoon. There is a work around. Just make a variable that is
parent, then use that instead. This uses the main goals of 3.0 to beat
the main goals of 3.0. 3.0 wants all that tricky event stuff, but it
also wants to be completely object oriented. Therefore objects (such as
your parent) are all variables at heart, declare a variable that points
to that object, and you own it.
// declare a variable that is parent
var myParent = parent;
// apply that instead of just using the command parent itself
myParent.gotoAndStop(2);
Now it works like a charm. The same applies to root.
NOTE: in AS 2.0 you
could just create a variable with a name, equals sign, and value. In
3.0 you have to declare it at first using var (like you should in
2.0!).
Lesson 2: Classes
Everything in
ActionScript 3.0 or the visual interface is part of what is called a
class. AS 3.0 now even runs its inheritance completely off of classes
as well (2.0 didn't), so understanding them would be a good idea.
Classes have methods, properties and events. A method does something,
like an action, such as gotoAndStop(1);. A property is just what it
sounds like, and gets or sets a property of the class (or specific
instance of the class) such as myMovieClip._alpha. An event is
something that sends out a call that something happened, such as
rolling over a button, etc.
For every class that
gets used inside flash (in the visual interface such as creating a
movie clip, or scripting in code) the class MUST be imported for it to
work. I know what you're thinking: "But I make movie clips without
doing this import thing, and it works fine...". That is because there
is a little file nested inside the Adobe folder in your Program Files
(or Applications on a Mac) that has a list of imports that it tells
Flash to do automatically. However, what if you wanted to import
classes yourself for use, such as a class not on that list, or for
making a class file, or countless other situations? You may not need to
worry about this, but when you're looking through a coder's scripts,
you'll see these little statements everywhere that look like this:
import flash.display.MovieClip;
import flash.utils.Timer;
This is the person
manually importing the classes, and in many cases, you have to. I would
suggest doing so in all situations if you can bear to memorize them, it
actually helps quite a bit in learning. The reason that not all classes
just get imported everywhere, is as follows: file size and speed. Each
class imported is a ton of code that is being placed in your .swf,
adding to size, and having to register variables, functions, etc. in
the flash player, so eating up resources on the computer. 3.0 is lean
and mean, no room for excess fat. Other than the basics that it imports
automatically into the main timeline, you tell it what to import, so
that no extra stuff has to be brought in.
Lesson 3: Properties
Many of the
properties in AS 3.0 are different. The general rule (which has it's
exceptions, like any rule) is that in 2.0, if it had an underscore in
front of it, now it doesn't, and if it was a number between 0 and 100,
now it's a number between 0 and 1.
AS 2.0:
// movie clip with instance name myClip_mc changed to 50% opacity in AS 2.0
myClip_mc._alpha = 50;
The above will change a movie clip to 50 percent opacity in AS 2.0.
AS 3.0:
// movie clip with instance name myClip_mc changed to 50% opacity in AS 3.0
myClip_mc.alpha = .5;
The above will change a movie clip to 50 percent opacity in AS 3.0.
Remember back in
math class, in order to do percents, you had to divide the percent by
100, then times it by the number? Well, we're cutting out an
unnecessary calculation, and passing it on to the programmer. 50 is now
.5, 80 is now .8, etc. It's all in the name of faster running of the
code.
For these type
of things, go to the help section, and do a search for the old property
in 2.0, and add in the word "migration". There is an entire section on
how to move from 2.0 to 3.0, with each change outlined.
Lesson 4: Events
Holy crap events have changed! In 1.0, we put stuff on a button usually. As in:
// script to give a button an action in 1.0, placed directly on the button
on (release)
{
doSomething();
}
In 2.0 they still let you do that, but said not to. Instead they said to put the code in the frame, and use a path like this:
// script to give a button named myButton an action in 2.0, on a frame, using a path
myButton.onRelease = function()
{
doSomething();
}
The reason that
there is no need to set a listener is because each possible event was
being monitored and called by each object. You just needed to define a
function for it to do. But that eats up precious CPU (a lot of it), and
since the name of the game in 3.0 is speed, it can't be that way any
more.
Now in 3.0, you can't do either of the previous methods any more. You
must make a function that has what you want it to do, and a listener
that waits for something to happen. And when something does happen, it
passes the event (yes, it is an actual object, not just an idea) to the
function, so you need to have an argument ready to take it (whether or
not you use it). Something like this:
// script to give a button named myButton an action in 3.0, on a frame, using a path
The function is
just a declaration of a normal function, but takes one argument, since
the listener passes one when it is dispatched. You don't need to use
that argument, just be ready to accept it without error.
The
addEventListener part gets a little tricky. First of all, make a path
to where you're listening for, just addEventListener will just listen
to the object that owns that frame, normally the main timeline.
myButton.addEventListener will add it to the button, so you are
watching that button, waiting for the event to happen to it.
The
MouseEvent.CLICK part is what you are listening for. There's a million
(slight exaggeration) events that can be watched for. What most light
programmers use are MouseEvent events. When you type in MouseEvent and
then the period in there, it will show the list of all the different
ones you can use for mouse related events, different ones are triggered
at different times. Experiment, you'll figure out what is what. The
help menu helps too (hence the name help menu).
The
ClickHandlerFunction part is easy. That's the name of your function. No
parentheses are needed, you don't get to decide what arguments get
passed, it passes the event whether you like it or not, and nothing
else. There are many properties of the event that you can use to figure
stuff out, but that is above the scope of this tutorial, this is for
the simple stuff only.
There will be more of these
tutorials in the future. The intent is to make a 2.0 to 3.0 transition
easier for the average Flash user. I hope it helps!
Comment #1
(Posted by Bhavik - parmar21in at yahoo.com) Rating
damn good tutorial for the beginners like me...
thanks a lot.. waiting for your article-2...
thank you very much
Comment #2
(Posted by Shannon - strutna at gmail.com) Rating
as simple as this seems, none of my 3.0 books are telling me this basic stuff! This makes so much more sense. Thank you! Got any more articles?
Comment #3
(Posted by andre@ampmusic.com - andre at ampmusic.com) Rating
Hi Bryan-
Thanks for the info. 2 questions:
1. In lesson 1, would "var myParent = parent;" need to exist in the movie clip you want to reference as parent? I don't see how this could work otherwise.
2. In lesson 3, wouldn't the compiler turn values of 0-100 into decimals (or hex or binary) anyway? If so, how are we gaining speed in the program by forcing decimals values on the user?
André
Comment #4
(Posted by Gwemps) Rating
For those of us trying to transition to "the beast", articles like this are nice plain English companions to the help flie and any books we pick up. Thanks.
Comment #5
(Posted by jp - jpgary at gmail.com) Rating
this is the most coherent and simplest tutorial about as3 I have seen, helped a lot to make me jump the hurdle
Comment #6
(Posted by Ravinder Kumar - ravinder_tawni at rediffmail.com) Rating
This article is pretty good for the user of AS 2.0. It is very helpful who want to switch in AS 3.0. Thanks to Bryan Grezeszak.
Comment #7
(Posted by erik - erikknippels at gmail.com) Rating
nice tuturial,
just what I needed to get started with AS 3.0,
so 5* from me!
Comment #8
(Posted by erik o - erik.olson at viget.com) Rating
Nice tutorial. Thanks for pointing out the basics to get people started.
Comment #9
(Posted by cookiebunnie - p_arai at hotmail.com) Rating
Hi Bryan,
Question:
If -->
function myFunction(evt:MouseEvent) {
// how do I detect which if button1 or button2 has been click without resorting to create 2 separate functions?
}
Previously, this would be easily solved with a simple -->
myButton.onRelease = function() {
myFunction(this._name);
}
._name or .name doesn't work here...please advise.
Comment #10
(Posted by kennywii - kenp at yahoo.com) Rating
myFunction(this._name)
AS3:
evt.target.name
Comment #11
(Posted by Bryan - bryan at elemental.us.com) Rating
I apologize to those that have asked me questions here, I incorrectly assumed that I would get notifications via e-mail, so was unaware of them. There are plenty of questions, so I will address each with a seperate comment, giving myself the already averaged rating so as to not boost my own score falsely!
Comment #12
(Posted by Bryan Grezeszak - bryan at elemental.us.com) Rating
-@andre@ampmusic.com
question1: yes, you would be inside the movie clip. Sorry if I didn't specify, the idea is to illustrate how to accomplish a very common task in 2.0, which is to call movie clip functions of the parent. In reality, what it is doing is creating an untyped var that is the parent, since parent itself is DisplayObject not MovieClip. Since this tutorial is for beginners, I did not explain that, but a more efficent way would be (parent as MovieClip).functionName();
question2: Yes it could be done in the compiler. However, the gain in speed is actually accomplished in your own code usually. In most dynamic formulas, you will end up with a value between 0 and 1, meaning you would then have to * that value by 100, adding a calculation in your own code. Again, this is mostly noticeable in advanced script, so I did not go in to too much detail, but good job noticing these things! Keeps questioning, it keeps people honest!
Comment #13
(Posted by Bryan Grezeszak - bryan at elemental.us.com) Rating
-@cookiebunnie
Remember how I said there was an object (I called it event) that gets passed to to function that gets called with a listener? That object holds a bunch of information, including the object that was doing the listening, as well as the object that dispatched the event. Now, for simple purposes, these are usually the same object, so the safest way for a beginners would be to use event.currentTarget, in your example it would be evt.currentTarget. That will be the object that you added the listener to, that caught the event. The best way to use that would be to declare a variable like this: var myObj = event.currentTarget;
This will make your variable untyped, which is slower, but you won't have to deal with converting it to the correct class, and since your learning, that's best.