Event Handlers versus Event Listeners
A number of ActionScript classes feature something called events. An event is raised by an object when a certain occurrence happens. For example, when someone hovers over a button symbol in a SWF, the Button.onRollOver event is raised for that particular Button instance. When the mouse is moved elsewhere, the Button.onRollOut event is raised for that same instance. These events take place whether or not anyone takes notice. If you want to actually do something in response to an event, you must manage it with an event handler or an event listener. The choice between these two is determined by the object — some objects expect handlers, some listeners — so hit the ol’ ActionScript Language Reference when in doubt. Handlers are relatively easy, but for some reason, listeners seem to perplex people at first. Let’s take a look at both.
Event Handlers
The most popular events probably belong to the Button and MovieClip classes, which happen to share many of the same (a movie clip can be a button, but not the other way around). To handle the Button.onRelease event, all you have to do is drag a button symbol to the Stage and give it an instance name via the Properties inspector. Use this name in a frame script to assign a function to the event.
myButton.onRelease = function() {
// do something
}
The other Button events work the same way, as do the MovieClip events and all events that require event handlers.
Any number of events can be handled. Just assign a function to each event, as necessary. A button that responds to a roll over, release, and roll out, for example, might look like this …
myButton.onRollOver = function() {
// do something
}
myButton.onRelease = function() {
// do something
}
myButton.onRollOut = function() {
// do something
}
Event Listeners
Managing event listeners requires a few more steps. A listener is accomplished with a generic Object instance. This object acts as a liaison between at least two others: the object that raises the event, and any objects listening for the event. Let’s look at a MovieClipLoader example.
var mcl:MovieClipLoader = new MovieClipLoader();
At this point, we’ve declared a variable, mcl, that points to an instance of MovieClipLoader. Now we’ll declare another variable, mclListener, that points to an instance of Object. (Sounds funny, I know, but we’re creating an Object object.)
var mclListener:Object = new Object();
This generic object will now become our liaison. At this point, the code looks very similar to the event handler approach.
mclListener.onLoadInit = function() {
// do something
}
I could have picked any event from the MovieClipLoader class, it really doesn’t matter. The thing to notice here is that a generic object is handling the event on behalf of the operative class instance. With event handlers, the operative class instance handles its own events.
Now that we have our listener, and now that a function has been assigned to one of its events on behalf of our MovieClipLoader instance, we simply need to subscribe the listener to mcl.
mcl.addListener(mclListener);
Done. Let’s see that all in one take:
var mcl:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadInit = function() {
// do something
}
mcl.addListener(mclListener);
To listen for more than one event, just follow suit with the event handler approach.
var mcl:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadStart = function() {
// do something
}
mclListener.onLoadProgress = function() {
// do something
}
mclListener.onLoadInit = function() {
// do something
}
mcl.addListener(mclListener);
June 25th, 2006 at 2:59 am
It would be great if you could talk a little about HOW to use Listeners, Broadcasters etc. inside AS 2 classes!
June 25th, 2006 at 7:25 pm
Caroosoh,
Event handlers, listeners, and broadcasters are used the same way in AS2 classes as they are in FLA timelines. Would you give me an example of what you’d like to see? I’ll be happy to explain.
June 26th, 2006 at 4:52 am
OK (and thanks for the chance).
I imagine a clip MultiLoader class that extends MovieClipLoader:
the constructor accepts one parameter, that’s an Array of JPG paths.
How to control the onLoadComplete (and other events, onLoadInit etc.) for every single JPG? How to insert it in the class?
If you open the gallery_tween.fla (mx 2004) example you’ve it all in a keyframe: I don’t understand how to use it in a class, how to make it work, how to design the class.
June 28th, 2006 at 11:40 am
Caroosoh,
I’ll tell you what. Your question is a good one.
I’ve added your topic to my list. This merits a full tutorial, rather than just a comments reply, so I will write something on multiple loads … keep your eyes peeled.
June 28th, 2006 at 12:02 pm
I’m waiting for the good tutorial, then
January 5th, 2007 at 12:10 pm
Argh, I’m so close…
Thanks to your tutorial above, I finally understand how everything is working with each other in regards to listeners and MovieClipLoader instances, but I’m after the tutorial that Caroosoh mentioned…many months ago…?
Where the listener and MovieClipLoader are inside a custom written class?
The way they are written above would only seem to work in AS1 not AS2.
January 6th, 2007 at 5:58 pm
Lopez,
The code in this blog entry is ActionScript 2.0, so you could certainly use it in an AS2 class file. I’m glad you mentioned the article I promised Caroosoh, because … heh, I still owe that one. It’s on my list, but I keep bumping it, because I simply haven’t yet made time. Thanks for the reminder! But certainly, if you want to experiment on your own, you could use the principles described above.
February 16th, 2007 at 8:52 am
I’m not sure, but I think I remember your name from the macromedia newsgroups. A lot of good people there.
The reason I stumbled here is because I’m also trying to write a custom class that uses the MovieClipLoader. To be honest, I don’t understand the classes principle fully, but I think my problem is that I want the class to create a container movieclip AND utilize that container to load a clip into using the MovieClipLoader. But I can’t let it extend two classes…
Structure looks like this (don’t mind the schematic syntax):
class Classname extends MovieClip {
function Constructor (){
createEmptyMovieClip(Container)
loadClip(Container)
}
}
February 16th, 2007 at 10:03 am
Tiemen,
You betcha, I’ve been on the Macromedia (now Adobe) boards for a long time.
To address your comment, it’s important you realize that writing classes does not inherently mean you must extend a base class. You can write a class that uses any number of existing classes — this is called “composition,” and it happens even if you simply use an array in your class — and that’s perfectly valid.
For something like what you describe, it makes sense to declare at least two properties: a) a
MovieClipproperty to store some movie clip reference (the target to be used byMovieClipLoader) and b) aMovieClipLoaderproperty to hold yourMovieClipLoaderinstance.In many regards, a custom class is nothing more than standard keyframe code. It’s probably more organized, but in the end, it’s “just plain ActionScript.”
Notice that the constructor is named the same as the class (not the word “constructor”).
What comes next is up to you, of course.
I don’t know in what way you mean to use
MovieClipLoaderhere. I imagine you might want to have a common occurrence transpire when the loaded asset is fully downloaded; if so, MCL’sonLoadInitevent will provide that information — but if that’s all this class is expected to do, I would just useMovieClipLoader. In the context of a larger class (or series of classes), something like this might make perfect sense … you might be writing a Slideshow class, and this could possible be a Slide class that handles its own loading. In that case, your Slide class may hold additional information, such as photographer, time the photo was made, perhaps a sound to play, etc.February 16th, 2007 at 4:40 pm
Wow first off I’d like to really comment on your entire blog. Initially I stumbled on your site by means of Google and placed the comment above, but after that I went to explore the rest of the blog and it is stunningly great! Much better then all the tutorial sites I have come through and the tone of your blog entries is truly very sympathetic and intelligent at the same time. The ideal combination (for me) to learn and accept from. And the joyful updates about Meridian (original name) are pleasant too when your head is spinning with code..
Regarding the above. I knew it would come down to writing lines of code, but as these are comments, I didn’t want to fully write out what I have going on, but this ’schematic’ way doesn’t quite cut it either, so let me explain. Of course my contructor function has the same name as my class.
What I want the class to do is to load external jpegs, using the movieClipLoader from a path passed as parameter. Secondly I’d like to manipulate the depth in which the container movieclip is created, so images can be placed behind or in front of certain objects.
And lastly I want to be able to manipulate the actions incurred when various event handlers of the movieClipLoader are invoked. Like you mentioned above.
I put it in one class, one function, but though the parameters are passed, the movieClipLoader doesn’t instantiate, leading me to believe what I posted in the previous post.
My code looks as follows;
class preLoader extends Movieclip {
//I had to extend it in order to use the createEmptyMovieClip, later on.
private var FILE = file_param
private var DEPTH = depth_param
public function actionLoad() = load_function
public function actionProgress() = load_progress
public function actionComplete() = load_complete
public function actionInit() = load_init
public function actionError() = load_error
function preLoader (file_param, depth_param) {
var loader_mcl = new movieClipLoader();
var listener_obj = new Object();
listener_obj.[loading handlers] {actionFunction}
//all the loading events, plus corresponding functions, see start of class
this.createEmptyMovieClip (”container_mc”, DEPTH)
loader_mcl.addListener(listener_obj)
loadClip(FILE, container_mc)
}
}
For once: movieClipLoader is not instantiated. Not initialized. Does nothing. And I know the part concerning the loading action functions is erroneous, don’t know yet how I can get that to work correctly.
February 18th, 2007 at 3:26 pm
Tiemen,
Hey, thanks for the kind words!
Your reaction is exactly the reason I hang out on the forums and write articles for this blog. That made my afternoon.
Sounds good. We’ll take this step by step, to match your three goals. So far, if this was your only goal, I would personally just use the
MovieClipLoaderclass. The same instance can be used repeatedly to load any number of JPGs into any number of movie clip containers.In the above example, the
MovieClipLoaderevents wouldn’t be of much use, because you can only track the downloading of one JPG at a time [Note! This is incorrect, as clarified in a later reply to Tiemen], but you could certainly load images in sequence this way, firing off a newloadClip()method as needed.First, a few thoughts about depth. Once the SWF is published — that is, once timeline layers are no longer part of the equation — depth occurs on a movie clip basis. Movie clips placed or created with ActionScript always appear on top of movie clips placed by hand in a timeline. In ActionScript 2.0, it is not possible to specifically move the child of one movie clip in front of the child of another: the movie clips themselves would have to be swapped, and all the children of both would move with them.
Now, if all of that is okay (and it has to be, unless you’re using AS3), then at this point, I would still — perhaps — not necessarily write a custom class to do the swapping. (I might, but then somewhere along the line, some class would have to keep track of all the images.)
For this, it would probably make sense to instantiate one
MovieClipLoaderinstance for each loaded image, so that each separate image could have its loading tracked. At this point, it might indeed be time to write a custom class, if only to have one place to manage all these instances. This could very quickly become complex, if you wanted to keep track of each instance’s events separately.Aha. Okay. Looking at your code …
… I see that you’ve scoped your
MovieClipLoaderinstance to the constructor function itself. This variable, because it is declared inside this function, only “lives” as long as the function is active. In effect, as soon as your custom class is instantiated, yourMovieClipLoaderinstance is deleted. Declare this variable as a private property at the top — outside any function — and initialize it, if you like, in the constructor or some other method.Well, yes and no. True, you need a
MovieClipreference in order to use thecreateEmptyMovieClipmethod, but it would make your class just as portable (re-usable) if thatMovieClipreference were, say, passed into the constructor. As a general rule, inheritance (extending a class) should only occur when the subclass (the new class) is an instance of the base class. YourpreLoaderclass doesn’t seem to need anonEnterFrameevent; it doesn’t seem to need_x,_y,_width,_height, or other position/scale properties normally associated with a movie clip. TheMovieClipclass defines dozens of properties, methods, and events, but — so far — it looks like you only need one of those (createEmptyMovieClip()), so I would caution against extending such a complex class unless you really need to. The overhead simply isn’t necessary.Does that make sense?
February 19th, 2007 at 5:01 am
Thanks David, for the extended reply. By the way, what are the tags you use to style your blogs/comments?
Regarding the issue again.
I figured that if I used the movieClipLoader class to load several clips into several containers using the same listener - this topic - they indeed would interfere. First off some basics… for me to understand the instancing of classes and event handlers, because actually, I don’t understand fully what happens. First I create an object instance and assign it to be an instance of the movieClipLoader class, and then I create an object which is defined using the event handlers onProgress etc. later to be used as listener, which will come into action only when you link this object to the movieClipLoader object using [movieClipLoader_instance].addListener([object_which_has_event_handlers_assigned_to_it])?
So if I want to be able to use different loading event handlers for different loading events I have to create new instances of the movieClipLoader because only one loading listener can be attached to each movieClipLoader instance? (Checking if I understood correctly.)
About depth; I knew indeed that all negative depth is reserved for objects on stage, that actionScript created objects can only have positive depths. But still I want to manager those depths in which I create the containers, later to be the images. This way I can use for instance one loader for the background images and one for content images on the pages. To load the images behind stage objects I have to use the swapDepths method, or simply create a background image container mc on the stage. Right?
[quote]Well, yes and no. True, you need a MovieClip reference in order to use the createEmptyMovieClip method, but it would make your class just as portable (re-usable) if that MovieClip reference were, say, passed into the constructor.[/quote]
Hmm this I don’t follow. When I initially created the class I didn’t extended anything, bucked the movieClipLoader part including the container-creation into the constructor, and got the “There is no method with the name ‘createEmptyMovieClip’.” error. How does that referencing work? And why doesn’t it give the same error about the loadClip method? Naturally it felt wrong to let this class be an extension of the movieClip class, because of the same reason you described, but I didn’t got it to work otherwise.
Well, I go on recreating the class using your tips, reporting back soon!
February 19th, 2007 at 6:46 am
class preLoader extends MovieClipLoader
private var FILE:String
private var DEPTH:Number
public var actionProgress:Function
private var loader_mc:MovieClipLoader = new MovieClipLoader();
private var listener_obj:Object = new Object();
private var container_mc:MovieClip = this.createEmptyMovieClip("container_mc", DEPTH);
//constructor
public function preLoader (FILE_param, DEPTH_param) {
this.FILE = FILE_param;
this.DEPTH = DEPTH_param;
}
public function movieLoad(FILE, DEPTH) {
listener_obj.onLoadProgress = function(targetMC) {}
loader_mc.addListener(listener_obj);
loader_mc.loadClip(FILE, container_mc)
}
}
Does not work (yet): Errors reported:
**Error** C:\Documents and Settings\Ghita Bouman\Desktop\Nieuwe Site\as\preLoader.as: Line 12: A class's instance variables may only be initialized to compile-time constant expressions.private var loader_mc:MovieClipLoader = new MovieClipLoader();
**Error** C:\Documents and Settings\Ghita Bouman\Desktop\Nieuwe Site\as\preLoader.as: Line 14: There is no method with the name 'createEmptyMovieClip'.
private var container_mc:MovieClip = this.createEmptyMovieClip("container_mc", DEPTH)
Not extending the MovieClipLoader class returns the same errors.
February 19th, 2007 at 6:47 am
eh.. my attempt to style it has removed some syntax, but the syntax is correct in the original, I promise
February 19th, 2007 at 1:49 pm
Tiemen,
We’re veering somewhat from the focus of the original blog entry, so I’d like to aim specifically more toward event handling/listening in this particular entry than toward class writing. That said, this is a good conversation, and thanks to your questions, I’ve researched the
Here are my replies (and thanks!).
MovieClipLoaderclass in greater detail — and have learned where I was mistaken in a few areas, so I’ll leave it in place.Mainly
<code>, occasionally<blockquote>, and mainly just typing.Each instance of a class — any class — represents a single object that has available to it all the properties, methods, and events defined by that class. In the case of
MovieClipLoader, you may invoke theloadClip()method as often as you like on a givenMovieClipLoaderinstance. If you load 50 images, you may even handle all 50 sets of events from that single instance — this is where I was incorrect earlier — though who knows how complex that might get. (In truth, it wouldn’t actually be 50 sets of events, but the same 6 events of anyMovieClipLoaderinstance … just … well, firing rather often, on behalf of each image.)If you have a single
MovieClipLoaderinstance, you may re-assign any number of functions to itsMovieClipLoader.onLoadInitevent, for example — but only one of those functions would be active at a given time. If you loaded images sequentially, that wouldn’t matter. If you used a singleMovieClipLoaderinstance and loaded 50 images simultaneously, the same function (the same event handler) would occur for each.In this sample code …
… you’ll see the “Image loaded!” message appear twice in the Output panel, but you’ll have no idea (except maybe visually) to determine which image loaded first, and consequently which image triggered the function first. [Note! This is embarrassingly incorrect. Every one of the
MovieClipLoaderevents carries with it a way to identify the target clip to which it is associated. I’m putting in this note in hopes I don’t steer anyone astray, but I’m leaving in the original wording because, hey, I make mistakes like anyone else, and a little humble pie is good for the soul.] This may suit you fine, or it may make sense for you to instantiate oneMovieClipLoaderobject for each image.On the other hand, the
MovieClipLoader.onLoadProgressevent lets you know which movie clip it’s loading into.In this sample, very similar …
… the
mcparameter indicates which container clip contains thebytesnumber of bytes.MovieClip.swapDepths()will do it.If there is not
MovieClipinstance to reference, then indeed, there is nocreateEmptyMovieClip()method on which to invoke the method. Functions are free-range and can be called anywhere; methods require an object instance; specifically an object instance that was instantiated from the class that supports the desired method.Currently, your class accepts two parameters:
… so make it accept three paramters, one of which is a movie clip reference.
As long as
containeris aMovieClipinstance, you can usecontainer.createEmptyMovieClip()in your class code.Incidentally, I strongly recommend you use post colon suffixes in your code. For example …
… because that keeps you more mindful of the datatypes you’re using. In addition, classes are, by convention, set in title caps, so
preLoaderwould more traditionally be calledPreLoader.Here is a rough skeleton of how I might approach the class you’re working on. Remember, I don’t know what your full purpose is, or what detail you want to add, but in case “an image is worth a thousand words,” maybe this will do better than my wordiness.
Note that your
movieLoadmethod accepts a new movie clip container reference with each call, in addition to a “name” parameter, which you could use as your instance name for a newly created clip. I see value in storing a singleMovieClipLoaderinstance and a singleObjectinstance for handling events — but I haven’t suggested how or where to handle these events, but don’t see in my mind’s eye what you’re after.I hope showing you this sort of stab-in-the-dark example isn’t a “dangerous” thing. I don’t mean to confuse matters at all.
February 19th, 2007 at 7:10 pm
Holy **** David, that’s a whopping reply!
I’m going to bed now, so I’ll keep it short..
You meant this part?
From what I’ve learned firing a bunch of loadClips on a single MovieClipLoader instance returns for each image separate event results, so indeed there we have no problems there, but that wasn’t exactly my issue.
I wanted the action taken on the 6 (5? onLoadStart, onLoadProgress, onLoadComplete, onLoadInit and onLoadError?) events to be manipulable from the outside, while the creation of a container clip and the loading itself remains hidden in the class.
Your example code looks very elegant as in the container-creation part & subsequent loading into it. Managing the depth of the container still has my preference, as this will allow multiple container mc’s on one “mc”, and still remain in control of their superposition (in contrast with the getNextHighestDepth()), for instance
movieLoad(background_mc, "layer 0", "ground.jpg", 0)movieLoad(background_mc, "layer 1", "trees.jpg", 1)movieLoad(background_mc, "layer 2", "clouds.jpg", 2)This way I won’t have to bother which movie loads first, which would be a problem using getNextHighestDepth. Oh well.. not yet the moment for finetuning :/
I’m not sure it this sequencing thing bothers me. I think I’ll work that out using the action I’m planning to use in the event handler functions.
My big question of tonight: How do I control those functions from the outside/ how do I paste entire functions between those handlers inside the class?
Oh and though it looks great, and worked out even greater, your rough sketch doesn’t work (here). All the MovieClip objects come out fine, all parameters come through fine, but the MovieClipLoader still won’t fire up.
Still a bit crucial in this whole custom MovieClipLoader class story
I’m amazed at your devoted feedback David, and I’m really sorry about letting blog entry become more and more a forum topic… that’s normally not what commenting is about :-/ But it sure is pretty frustrating not getting this simple class to work.
The event handlers themselves are after reading this a peace of cake though.
February 22nd, 2007 at 9:13 am
Tiemen,
No worries.
I have one or two more comments, but then we’ll round out this conversation — at least, for the time being. I’m about to write a blog entry on the topic of using
MovieClipLoaderin a class (many people have shown interest, and I promised ages ago I’d put it “on my list,” so it’s time to deliver).That’s the nice thing about programming: the preference is yours, as a programmer.
Not sure what you mean by that. If you were incrementing depths yourself, it would amount to the same thing, really.
Functions may be passed around just like objects (they are objects), so from an outside-control point of view, it’s not especially difficult. How to manage an number of such connections, that’s the part that has my scratching my head, because some events carry with them a reference to the loaded object (
onLoadProgress), while others (onLoadInit) do not — at least, not that I can see.There are only five events, by the way. Thanks for noticing that!
March 9th, 2007 at 9:37 am
This was a great tutorial, thanks for clearing a few things up.
Alas, like others, I am still running into problems.
I am very new to Flash and Actionscript but have gotten a few things to work.
I have a main movie clip which loads several *.ai images, basically a map with different sets of icons. In one of the layers there are a couple hundred icon text pairs. I am trying to attach a listener to each one programmatically so that I can do some work when they are clicked; grab the text and change the icon color.
I have an actions frame with code that adds zoom and preview buttons as well a context menu. I am trying to add the listeners in the same section of code. I can add a click listener event to the movie clip itself and that seems to work. but when i try to loop through the properties of the movie clip and add a listener I am unable to catch the event.
I am not adding this code to on() or onClipEvent().
Code:
var stationListener:Object = new Object();
stationListener.onPress = function()
{
trace( "Station press..." );
};
stationListener.click = function()
{
trace( "Station click..." );
};
stationListener.mouseDown = function()
{
trace( "Station mouseDown..." );
};
for( var key:String in map.stations )
{
var obj = eval( map.stations[key] )
obj.addListener( stationListener );
trace( "" );
trace( "Key:" + key );
trace( "Value:" + obj );
trace( "Type:" + typeof( obj ) );
};
Outputs:
Key:instance1
Value:_level0.layers.stations.instance1
Type:object
From Debug List Object:
Movie Clip: Frame=1 Target="_level0.layers.stations"
Shape:
Edit Text: Target="_level0.layers.stations.instance1" Variable= Visible=true Text = STN1\r"
From Debug list variables:
Movie Clip: Target="_level0.layers.stations"
Edit Text: Target="_level0.layers.stations.instance1"
htmlText = "STN1\r",
tabIndex = undefined, textHeight = 8,
text = "STN1\r",
filters = [object #27, class 'Array'] [], bottomScroll = 1, password = false, embedFonts = false,
hscroll = 0, maxscroll = 2, length = 5, textColor = 0,
multiline = true, html = false, scroll = 1, variable = null,
gridFitType = "pixel",
restrict = null, border = false, selectable = false, background = false,
backgroundColor = 16777215, condenseWhite = false, maxhscroll = 0, styleSheet = undefined,
type = "dynamic",
antiAliasType = "normal",
autoSize = "none",
mouseWheelEnabled = true, textWidth = 13, wordWrap = false, maxChars = null,
thickness = 0, borderColor = 0, sharpness = 0
I was hoping that I did not have to go through and convert all of the icons to symbols.
Any thoughts, comments or help is greatly appreciated.
March 9th, 2007 at 9:47 am
Travis,
You nailed it, actually — those icons do need to be symbols. It’s the symbol wrapper that makes all the difference, because until your imported image is a movie clip, that artwork is not an instance of the
MovieClipclass. The class definition of the object at hand is fundamentally responsible for what that that object can do.In your code, for example, what is
obj? Clearly, it refers to whatevermap.stations[key]is — but (and here’s the important part) what datatype ismap.stations[key]? Does that datatype support anaddListener()method?In the original article, the
mcl.addListener(mclListener);line works becausemclis an instance of theMovieClipLoaderclass, and that class features anaddListener()method.March 9th, 2007 at 10:04 am
Wow, thanks for the quick reply.
I was afraid that is what the answer would be.
So I guess the question is should I do this programmatically or manually? I had gotten atleast a portion of this work by converting a couple of the pairs to movieclips. However, to do this I had to “break apart” all of the grouping within flash which caused my zoom to stop working.
In a language I am actually familliar with, I would create my own nested movieclip sublass that holds an instance of the icon( shape ) and the text portion each as its own movieclip, so that I can control the changes individually and still tie the event handling to the overall symbol. However, manually creating these symbols doesnt seem to work this way.
I do not expect you to give me all the answers here, I am just not really sure what to start looking for in the documentation or tutorials.
Would I be better off trying to do this in Flex?
Thanks again for your help.
March 9th, 2007 at 10:26 am
Travis,
Flex operates in ActionScript 3.0 land, which requires a whole new map. The principles are the same — you would still need to convert those raw images into whatever class instance meets your needs — but you’d have to change gears quite a bit. Flex Builder 2 has no timeline or drawing tools. It’s a different IDE that caters to a different sort of developer.
That said, Flex Builder 2 is arguably “just another” ActionScript editor, same as Flash. I put that in quotes because both applications are immensely complex, and Flex Builder 2 is an awesome code editor — but the point is that ActionScript is what matters. The tool used to write it isn’t nearly as important as what the language requires or is capable of. (Honestly, you can produce SWFs without any Adobe software at all [see osflash.org].) So even in Flex, you’ll have to mass-convert those images.
The Flash IDE is programmable via JSFL, and that might be a good solution for you. See the “Extending Flash” book in the documentation. If you’re comfortable with JavaScript, you’ll find you can program the IDE by way of a DOM what works, in principle, to the DOM in HTML.
April 28th, 2008 at 6:40 am
One thing, that, i was searching explanation for is :
Why there are two types of “binders” ie.
1) AddEventListener
2) AddListener.
The 2nd one can be understood, but the 1st one always confuses, as why there is the necessity of mentioning the type of event which is going to be bound with the object. As in the following case :
mylistener.click = function () { // do something }
mybutton.addEventListener ( “click”, mylistener )
April 28th, 2008 at 7:55 am
Swan,
I can’t answer authoritatively why
addEventListener()needs the seemingly redundant information, but for what it’s worth, that method is the preferred approach in ActionScript 3.0. With very few exceptions,addEventListener()is the new way to handle events. The other approaches, includingaddListener()are a result of new functionality added to Flash over the years. So the reason there are two “binders,” at least in ActionScript 2.0, may well be that various teams worked on various implementations of the API over various years.April 29th, 2008 at 12:22 am
Thanks,
Btw, the good thing i like about quip, is that you ALWAYS respond, with a reply.
May 7th, 2008 at 10:55 pm
Swan,
Thanks! I really do try to always respond. Sometimes it takes me a very long time.
August 1st, 2008 at 8:06 am
Hi, David! Thanks for this informative article. I’m currently in the process of understanding the difference between event handlers and event listeners and your article has helped a lot (although I’m still a bit confused, but considerably less confused than I was before reading your explanation
). Would you be so kind as to clarify something for me? When you say “an event is raised by an object”, is it the same as saying “an object broadcasts an event”. For example, when you press a button (let’s say it has the name myBtn), the myBtn button instance “raises the onPress event”, and if an onPress event handler method is assigned to myBtn, then the onPress event handler method is invoked and then something happens (plays a sound, for example). Would this explanation be somewhat correct as well:
When myBtn is pressed, it “broadcasts”: “hey, I’ve just been pressed!”. And then the event handler method (which is assigned to the myBtn button) is activated and then something happens.
Would that be a correct explanation? Because the way I understand it is that with event handlers, the object that “broadcasts” the event is also the one listening out for when that specific event is broadcast (so the object is kinda like talking to itself). Where as with event listeners, one object broadcasts the event and then another different object (the listener object) listens out for those events that are broadcast.
August 11th, 2008 at 10:13 pm
automator,
I would say yes. In day-to-day discussions, I generally hear the concept in question described as “an event being raised,” “an event being triggered,” and “an event being broadcast.” All of these refer to an event occurring, and then it’s up to your event handler function to “handle” the event.
The part where it gets hazy — and this may be 100% in the way I (mis)represented the concept — is that even listeners can be said to handle events. That makes the phrase “event handlers vs. event listeners” potentially confusing.
What I’m calling “event handlers” in this article are essentially nothing more than properties, if you look carefully at it (and maybe I should have been more careful!
). The
Button.onRelease“property” is assigned to a function, which makes it actually do something when its namesake event occurs.What I’m calling “event handlers” have a one-to-one correspondence between the event and the triggered function. What I’m calling “event listeners” can have a one-to-many correspondence. You might, for example, have 100 different listeners all listening for a particular event to be broadcast. It’s in that scenario that the term “broadcast” seems (to me) like a good fit. But out of laziness, perhaps, I often use the word “broadcast” for all of the above.
I hope that clears the somewhat muddy water!
December 18th, 2008 at 7:25 pm
Hello
As a fresh www.quip.net user i just wanted to say hello to everyone else who uses this bbs