Archive for February, 2008

Using Delegate to have the right scope when using TweenLite, Tweener and Events in ActionScript 2

Not so long ago I was having a bad day using Flash 8 and ActionScript 2 just after completing a project in ActionScript 3. Now this Dan Hunter dude made a comment saying I should try using this Delegate class. Well last week I thought I should give it a try so I head over the blog post and try to figure out what it is used for. I had heard the word Delegate before, but never quite understood it.

So I look at the post and it is exactly what I hate in a post; it is very technical and not quite to the point. I don’t think I am a bad programmer and I should understand stuff like that but there is something missing in the post: why should I use this class in the first place?

Well I am going to tell you why you should used this class; because it will give you the right scope of the function called by the delegate function. Ok, ok maybe I’m not quite clear either, but go read this article on how to use the Delegate class and you should understand everything. I found it while installing the new version of Flash Develop (beta 6). The real useful thing about the Delegate class is that it permits you to use the “this” you want inside the function you want.

Here is my example using events; let’s start by using a simple button on click custom event. So you make this custom button class that handle the rollover and rollout internally and when you have a onrelease event, you send an event to the class containing the button. You do so in order to keep your code clean and well organized. Here is the code you would have for the event listener inside the class that will contain the custom button:

1
2
3
4
5
myCustomButton.addEventListener("click", handleClick);
 
function handleClick(evt:Object):Void{
  trace (this)//this will actually refer to myCustomButton instead of the containing class
}

By using the Delegate class, “this” will refer to the containing class. Here is how you do it:

1
2
3
4
5
myCustomButton.addEventListener("click", Delegate.create(this, handleClick));
 
function handleClick(evt:Object):Void{
  trace (this)//this will refer to the containing class
}

This will save you the trouble of having to find in which scope you are and also having to use this._parent all the time.

Another good use of the Delegate class is when you use the onComplete argument with Tweener or TweenLite. When you use the onComplete argument with both these Tweening engines, it will call the function you specify it when it will be done Tweening. With Tweener this function will be scoped to the MovieClip your doing a Tween on and with TweenLite the function will be scoped to the TweenLite Object which is not very convenient. Here is how you would use the Delegate class for these situation:

1
2
3
4
5
6
7
Tweener.addTween(myCustomButton, {_alpha:100, time:1, onComplete:Delegate.create(this, doNextStep)});
 
TweenLite.to(myCustomButton, 1, {_alpha:100, onComplete:Delegate.create(this, doNextStep)});
 
function doNextStep():Void{
  trace (this)//this will refer to the class containing the Tweening code
}

Well this will save me a lot of trouble. I was thinking that I was a good programmer and that experience didn’t really mean anything but these little things, like using the Delegate class to have the scope you want or know that TweenLite is faster than Tweener which is faster than the Adobe Tween classes,  can only be acquired with experience and they make your days a whole lot better. This kinda is a lesson of humility.

, ,

2 Comments


Flash CS3 extension to compress bitmap faster

Have you ever had to import a sequence of images in Flash and then had to change the compression by hand for each of the images imported? It’s really boring to do and also time consuming. I mean for each image, you have to select it in the library, right click, go in properties, choose the compression and than click apply. I couldn’t believe that there wasn’t any better way to do this. This week I saw a video by Lee Brimelow on how to create custom panel in the Flash IDE and decided to take the matter in my own hands.

So at the bottom of this post is the link to download my extension. It’s not perfect, I think I could still had some options, but it does pretty much what I wanted.  Basically, it lets you select multiple bitmaps in your library and change the compression setting once for all of them. The zip file also contains the source code of the package if you want to play with it. If you just want to see how it is done, I will simply paste the code here. There is 2 kind of language in there: ActionScript 3 and JSFL. The JSFL is the string that the MMExecute function takes. Here is all of it:

[as]

compress.addEventListener(MouseEvent.CLICK, manageClick);
function manageClick(e:MouseEvent):void{
if (numCompress.text != “”){
var myNum:int = int(numCompress.text);
if (myNum < 0){
myNum = 0;
}
if (myNum > 100){
myNum = 100;
}
var jsfl:String = “var selItems = fl.getDocumentDOM().library.getSelectedItems();for (var i = 0; i < selItems.length; i++){if (selItems[i].itemType == 'bitmap'){selItems[i].allowSmoothing = " + mySmooth.selected + ";selItems[i].compressionType = 'photo';selItems[i].useImportedJPEGQuality = false;selItems[i].quality = " + myNum + ";}}"
MMExecute(jsfl);
}
}

[/as]

Here is the JSFL formatted in an understandable kinda way:

[as]

var selItems = fl.getDocumentDOM().library.getSelectedItems();
for (var i = 0; i < selItems.length; i++){
if (selItems[i].itemType == 'bitmap'){
selItems[i].allowSmoothing = " + mySmooth.selected + ";
selItems[i].compressionType = 'photo';
selItems[i].useImportedJPEGQuality = false;
selItems[i].quality = " + myNum + ";
}
}

[/as]

It was pretty simple to do, but it seems strange how you use the JSFL since you have to put it all on one line in order to call the MMExecute function. Well here it is, have fun with it.

Compress Images custom panel

, , , ,

7 Comments


Video tutorial on how to use GOASAP

I have talked a bit about GOASAP, but I didn’t really have the time to check it out; well mosessupposes made a good video tutorial on how to create your own animation engine. Be sure to check it out because it’s pretty good.

, , ,

No Comments


The right way to do RollOver Event in AS3

I have been asking myself this question for a long time now. I see two ways of doing a roll over using ActionScript 3. The first one is pretty straight forward and it is the one you’ve seen everywhere. Here is some sample AS3 showing how to do it:

button.addEventListener(MouseEvent.ROLL_OVER, manageMouseOver, false, 0, true);
button.addEventListener(MouseEvent.ROLL_OUT, manageMouseOut, false, 0, true);
 
function manageMouseOver(event:MouseEvent):void{
  //your over code here
}
 
function manageMouseOut(event:MouseEvent):void{
  //your out code here
}

This is the classical way off doing thing. Doing it this way implies that for all your button you always have 2 listeners to do your rollovers. There is another way of doing this that will always use only one listener. Here it is

 
button.addEventListener(MouseEvent.ROLL_OVER, manageMouseOver, false, 0, true);
 
function manageMouseOver(event:MouseEvent):void{
  button.removeEventListener(MouseEvent.ROLL_OVER, manageMouseOver);
  button.addEventListener(MouseEvent.ROLL_OUT, manageMouseOut, false, 0, true);
  //your over code here
}
 
function manageMouseOut(event:MouseEvent):void{
  button.removeEventListener(MouseEvent.ROLL_OUT, manageMouseOver);
  button.addEventListener(MouseEvent.ROLL_OVER, manageMouseOut, false, 0, true);
  //your out code here
}

Doing it it this way, there will be less listener active at the same time, but each rollover will do 4 more actions. So is having less listeners worth doing more computations; is there situations where you should use one technique more than the other; or it has so little impact that we should not care about it?

I’d really like to know.

Following the indication in the comments I investigated the difference between MOUSE_OVER and ROLL_OVER and found that most of the time it is better to use ROLL_OVER.

Edits May 5th 2010
Because this post is now receiving a lot of traffic and it is one that I wrote so long ago, I felt obliged to update it a little. First off I would like to say that I would stick with method number 1 because it is just way easier to understand the code and method number 2 doesn’t save much (it just makes things more complicated, keep it simple). Secondly, I did some edits to the code itself; I removed the bad habits I used to have. I switched the MOUSE_OVER for ROLL_OVER because 99% of the time that is what you will need. I also change “e:MouseEvent” to “event:MouseEvent” as it is easier to read and it is the best practice that Adobe is pushing. Finally, I added “false, 0, true” at the end of my listener functions to set weakReference to true. In short, this is a fail safe if you forget to remove your listeners when you don’t need your button anymore. The button won’t be held into memory by the listeners. I just thought you should know.

,

30 Comments


SWFAddress and the new Google Analytics (ga.js)

I’m always playing a bit with SWFAddress, SWFObject and Google Analytics. SWFAddress has a nice features which is that it will advise Google Analytics when you change a page inside your main swf movie. That gives you the ability to do tracking on your website. Pretty neat!

Has some of you might know, Google Analytics has released a new tracker code (from urchin.js to ga.js). What more does it do for you right now? Not much, it’s supposed to be smaller in size and that’s about it. No event yet (there was a lot of buzz around events in Google Analytics and there is actually documentation on how to implement them but they are still in closed beta; we will have to wait on this one), no new functions. But if your launching a new website I would advise putting the new tracker code (ga.js) because it will save you maintenance time when you will want the new features.

So does SWFAddress works with the new code? Well the answer is yes, and it is pretty easy to make it work here is sample code showing you how to do it:

<script type="text/javascript">
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
var pageTracker = _gat._getTracker("UA-xxxxxx-xx");
pageTracker._initData();
</script>
<script type="text/javascript" src="js/swfobject.js"></script>
<script type="text/javascript" src="js/swfaddress.js?tracker=pageTracker._trackPageview"></script>

The most important part of the code is the last line where you tell SWFAddress which tracker to use. That’s it! I hope this saves you some time.

, , ,

23 Comments