Archive for the ‘AS 3.0’ Category

Enabling Handcursor on a MovieClip having dynamic TextField in AS3

October 10, 2008

You can enable the hand cursor on a MovieClip by defining the following statement

MovieClip.buttonMode = true;

However the solution does not work in-case you have a dynamic textField in that movieclip. To enable hand in this case you have to additionally write the following statement

MovieClip.mouseChildren = false;

The reason is that the mouseChildren property determines whether or not the children of the object are mouse enabled. If an object is mouse enabled, a user can interact with it by using a mouse. The default is true which makes the dynamic textfield interactable and due to the textfield behaviour the flash player does not show the hand-cursor.

Attaching MovieClip from library by passing classname as a string in function in AS3

October 10, 2008

The post contains a solution for a case where you need to attach a Library symbol and you have to pass that class name as a string to the function.

The approach followed here is by using the getDefinitionByName utility which interprets the string and convert it into a Class. Then you can use a new syntax with that particular class. Following is a code for the same solution and you can download the source files from here. The “testMC” here is a movieClip in library with the className as testMC and BaseClass as flash.display.MovieClip

import flash.utils.getDefinitionByName;


function addMovieFromLibrary(mcIName:String){
var tMC:Class = getDefinitionByName(mcIName) as Class;
var newMc:MovieClip = new tMC() as MovieClip;
addChild(newMc);
}


Trace from the browser, using standard trace()Trace from the browser, using standard trace()

August 22, 2008
Some great 3rd party debug tools have been released in the past few months that expand upon the standard trace() in Flash. I recently wrote about one of them. Unfortunately, I’ve noticed myself not using these tools as often as I would like because its usually easier and quicker to just use trace(). The biggest drawback about trace, however, is that there’s no way to output from the browser … or is there?
The other day I stumbled upon an article by Josh Buhler at actionscript.org that shows you how to install the Flash Debug Player that’s buried in the application folders of Flash. The Debug Player, along with a text file, allows you to view standard traces from a swf in the browser. Now, if you’ve already read his article skip on down to the bottom of this page because I’ve added a step that will make you even happier. If you haven’t read his article yet, go on what are you waiting for? If, on the other hand, you like step-by-step instructions that get you up and running the fastest, I’ve recapped his process below. I’ve done this on both the mac and pc and can’t live without it now.
1) Uninstall your Flash Player
Find the uninstaller here: Adobe Flash Player Uninstallers.

Even though this is the first step, this is the one that you’re going to question the most, should I really uninstall my Flash Player and install the Debug Player? The answer is an emphatic “yes”. The Flash Debug Player is the exact same player with a very nice extra feature.

2) Install the Flash Debug Player

Find the installer here: Adobe Flash Debug Players

3) Verify installation of the Flash Debug Player

Restart your browser and right-click (ctrl-click) on a swf. You should have the “Debugger” option in the context menu, like the example below. Flash Debug Player

4a) Create a text file named “mm.cfg”

Save the file here:

OSX -
MacHD:Library:Application Support:Macromedia:mm.cfg
Windows XP -
C:\Documents and Settings\username\mm.cfg
Windows 2000 -
C:\mm.cfg
Linux -
home/username/mm.cfg
4b) Add properties to mm.cfg
ErrorReportingEnable=0
TraceOutputFileEnable=1
MaxWarnings=0
FLASH DEBUG PLAYERS 9,0,28,0 AND NEWER
4c) The property TraceOutputFileName is no longer needed in mm.cfg. The default location of flashlog.txt has changed and cannot be modified from the following locations:
OSX -
MacHD:Users:username:Library:Preferences:Macromedia:Flash Player:Logs:flashlog.txt
Windows -
C:\Documents and Settings\username\Application Data\Macromedia\Flash Player\Logs\flashlog.txt
Linux -
home/username/Macromedia/Flash_Player/Logs/flashlog.txt
FLASH DEBUG PLAYERS 9,0,16,0 AND OLDER
4c) Add the property TraceOutputFileName to mm.cfg
OSX -
TraceOutputFileName=MacHD:Users:username :D esktop:flashlog.txt
Windows -
TraceOutputFileName=C:\Documents and Settings\username\Desktop\flashlog.txt
ALL FLASH DEBUG PLAYERS
5) Test the Flash Debug Player

Either publish a swf that uses trace() and view it in the browser, or surf around and find out what other people have been tracing in their movies (that’s one of my favorite options). The traces have been output from the browser to the text file. Open up flashlog.txt and see for yourself, you know you want to.

And there you go. I’m sure many of you are extremely happy right now, and you should be, this is a great tip. But after a few uses, you’re going to get really annoyed opening and closing the text file to view the new traces … if only there was a way to view the text file being updated in real time like the Output window in Flash. Here’s the new step that will make you rejoice.
NEW STEP …
6) View the text file updating in real time
OSX -
Open Terminal
At the prompt type:
>> cd <path to flashlog’s directory>
>> tail -f flashlog.txt
Windows -
Go to Windows Server 2003 Tools, and download Windows Server 2003 Resource Kit Tools near the bottom of the page. Although it says Windows Server 2003 all over the page, its also made for Windows XP.
Install
Open Command Prompt
At the prompt type:
> cd <path to flashlog’s directory>
> tail -f flashlog.txt
Browse to a swf online that uses trace() and watch the magic. Terminal and Command Prompt display the contents of flashlog.txt as it changes … its just like having Flash’s Output window, except this one works in the browser!!
Isn’t this great? Like I said earlier, I’ve gotten this to work on both the mac and the pc and can’t live without it now. If you have any questions about these steps, feel free to email me or comment below and I’ll be glad to help.
OPTIONAL WINDOWS STEPS …
7) Create a batch file to quickly load up the flashlog in tail
Create a text file and rename it flashlog.bat
Right-click on the batch file and select “Edit”
Add the following content to flashlog.bat:
cd <path to flashlog’s directory>
tail -f flashlog.txt
Double-click on the batch file to see it working.
8) Create a shortcut to the batch file to set the Command Prompt colors and options
Right-click on the batch file and select “Create Shortcut”
Right-click on the shortcut and select “Properties”
To view the Command Prompt maximized change the pulldown under “Run:”
To change the colors of the Command Prompt select the “Colors” tab
Unfortunately the “Font” tab options are very limited
Under the “Options” tab, select “QuickEdit mode” to be able to easily select and copy and paste
Tip for copying and pasting in the Command Prompt:
Select the text you want to copy and then right-click it, this puts the selected text into the clipboard … now just hit ctrl-v or paste in any other program.

Close out of the properties and double-click on the shortcut to see the flashlog with your colors and options.

MXML ActionScript Classes

August 10, 2008

As you know, all MXML files are converted to ActionScript Classes which are later compiled in SWF file. If you want to view / study these automatically generated classes, you can use Compiler Argument -keep-generated-actionscript in Flex Builder Project.

In Flex Builder navigate to Project > Properties > Flex Compiler > Additional compiler arguments and add following configuration: -keep-generated-actionscript

This will create a folder named generated in project source folder which will have all ActionScript classes which Flex Builder automatically generates from MXML ({MXML file name}-generated).

Copying objects with Flash.utils.ByteArray

July 17, 2008

I have been exploring the ways to copy an Array object to a new Array with less of the effort. Reason being the following statements in ActionScript

var arrayA:Array = new Array(”Jack”,”Steve”,”Mark”,”Ted”);
var arrayB:Array = arrayA;

The above statements appears to create a copy of arrayA, however in the actual it creates a new reference to the arrayA object. The problem is that if you execute any operation on arrayB object now it will impact the arrayA eventually. For example:

arrayB.pop();
trace(arrayA);

The statement is supposed to trace “Jack,Steve,Mark,Ted” whereas it will trace “Jack,Steve,Mark”.

To overcome this problem we use the following methodology

var arrayA:Array = new Array(”Jack”,”Steve”,”Mark”,”Ted”);
var arrayB:Array = new Array();
for(var i:int = 0; i < arrayA.length; i++) {
arrayB[i] = arrayA[i];

}
arrayB.pop();
trace(arrayA);

Now it will trace the desired result i.e. “Jack,Steve,Mark,Ted” and if you trace arrayB then it will trace “jack,Steve,Mark”

This methodology is very good when you are dealing with single array objects but when it comes to Nested Arrays it is really a tedious job as you have to look for every inner object of an array if it is an Array type and then again create a new array and copy it’s element. To overcome this we can use now the ByteArray class of Flash.utils package

You can review the following code used to copy an array. There is a disadvantages of using the ByteArray and that is you will loose on some speed. The ByteArray.Read method is slower than copying an Array. You can see a benchmark here

——————————–
Copying a 100000 elements array
——————————–
Copy with loops starts at :: 802504163
Copy with loop ends at :: 802504210
Time elapsed :: 47 milliseconds
Copy with ByteArray Starts at :: 802504257
Copy with Byte Array :: 802504382
Time elapsed :: 125 milliseconds

There is certainly a significant amount of processing time which ByteArray take however it is eventually helping us out when it comes to copying nested objects.

Download the fla from here.

Here is the code for the same.

——————————————————–

——————————————————–

import flash.utils.ByteArray;

var tDate:Date = new Date();
var iStartTime:uint;
var iTime:uint;
var byteArray:ByteArray = new ByteArray();

trace(”——————————–”);
trace(”Copying a 100000 elements array “);
trace(”——————————–”);
//———- Create and Populate Array ———
var arrayA:Array = new Array();
for (var i:uint; i<=100000; i++) {
arrayA.push(Math.random()*i);
if (i == 100000) {
copyArray();
}
}

//———– Copy Array using Loops ——–

function copyArray():void {
tDate = new Date();
iStartTime = tDate.time;
trace(”Copy with loops starts at :: ” + iStartTime);
var arrayB:Array = new Array();
var arr_len:uint = arrayA.length -1;
for (var i:int = 0; i <= arr_len; i++) {
arrayB[i] = arrayA[i];
if (i == arr_len) {
tDate = new Date();
iTime = tDate.time;
trace(”Copy with loop ends at :: ” + iTime);
trace(”Time elapsed :: ” + (iTime – iStartTime) + ” milliseconds”);
copyWithByteArray();
}
}
}
//——- Function copy with Byte Array ———
function copyWithByteArray():void {
tDate = new Date();
iTime = tDate.time;
trace(”Copy with ByteArray Starts at :: ” + iTime);
byteArray.writeObject(arrayA);
byteArray.position = 0;
var arrayB:Array = byteArray.readObject() as Array;
tDate = new Date();
var iByteArrTime:uint = tDate.time;
trace(”Copy with Byte Array :: ” + iByteArrTime);
trace(”Time elapsed :: ” + (iByteArrTime – iTime) + ” milliseconds”);
}

Resizing button component on the fly

July 9, 2008

We have encountered a situation where the the UI button label was changing frequently in Flash CS3. So basis on that we have to resize our button component as the label changes. There is no inbuilt AutoResize feature in button component so what we have done is, get the size of the label and then set the width of the button. Following is the code we have implemented in this case. Put a UI button on stage and name it “_btn”. You can download the source files from here.

import flash.events.Event;
//———-
var t_arr:Array = ["This is string 1","Hello","Hello to String 3","Hello to String 4","Hello to String 5","This is a long string NOW "];
//——— Set the button textfield properties ———-
_btn.textField.autoSize = TextFieldAutoSize.LEFT; // We need to set the autosize to LEFT?RIGHT or CENTER instead of NONE
_btn.textField.multiline = false; // Make sure the multiline is false in this case to get proper dimensions
_btn.label = t_arr[0];
_btn.textField.addEventListener(Event.RENDER,resizeBtn); // Add an event listener to textfield on render event
_btn.addEventListener(MouseEvent.CLICK,clickHandler);
//——– Resize the button ———–
function resizeBtn(evt:Event):void{
// trace(evt.target.width+” “+evt.target.parent.width);
_btn.width = evt.target.width+5;
_btn.validateNow();

}
//———— Handle button click ———
function clickHandler(evt:MouseEvent):void{
_btn.label = t_arr[Math.floor(6*Math.random())];
}

Loading library assets from flash9 swf to Flex

July 9, 2008

This is a prototype to load external flash9 swf file into flex and using the library items from the swf. In given example we have two library symbols with linkage ids (”mc1″, “mc2″).

Just make sure when you create a movieclip from these definitions, you firstly add these to a UIComponent and then that component to stage or any container, otherwise there will be a conversion error you will be getting

You can download sources from here

Following is the code for the same.

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” creationComplete=”init()” layout=”absolute”>

<mx:Script>

<![CDATA[

import mx.core.UIComponent;

//-------- Declare Variables --------

private var swfLoader:Loader;

private var fileURL:URLRequest;

//----- Initialize Function ------------

private function init():void{

//    Security.allowDomain("*");

swfLoader = new Loader();

_fileURL = new URLRequest("sample.swf");

configureListeners(swfLoader.contentLoaderInfo);

try{

swfLoader.load(_fileURL);

}

catch(e:IOErrorEvent){

trace(e.toString());

}

}

private function configureListeners(dispatcher:IEventDispatcher):void {

dispatcher.addEventListener(Event.COMPLETE, onSWFLoaded);

dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);

dispatcher.addEventListener(Event.INIT, initHandler);

dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

dispatcher.addEventListener(Event.OPEN, openHandler);

dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);

dispatcher.addEventListener(Event.UNLOAD, unLoadHandler);

}

private function completeHandler(event:Event):void {

trace("completeHandler: " + event);

}

private function httpStatusHandler(event:HTTPStatusEvent):void {

trace("httpStatusHandler: " + event);

}

private function initHandler(event:Event):void {

trace("initHandler: " + event);

}

private function ioErrorHandler(event:IOErrorEvent):void {

trace("ioErrorHandler: " + event);

}

private function openHandler(event:Event):void {

trace("openHandler: " + event);

}

private function progressHandler(event:ProgressEvent):void {

trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);

}

private function unLoadHandler(event:Event):void {

trace("unLoadHandler: " + event);

}

//-----

private function onSWFLoaded(event:Event):void{

var mClip:Class = event.target.applicationDomain.getDefinition("mc1") as Class;

var mClip1:Class = event.target.applicationDomain.getDefinition("mc2") as Class;

var mClipInstance:MovieClip = new mClip() as MovieClip;

var mClipInstance1:MovieClip = new mClip1() as MovieClip;

//trace(mClipInstance.totalFrames);

var uiComp:UIComponent = new UIComponent();

uiComp.addChild(mClipInstance);

uiComp.addChild(mClipInstance1);

addChild(uiComp);

uiComp.x = 100;

uiComp.y = 100;

uiComp.getChildAt(0).x = 150;

}

]]>

</mx:Script>

</mx:Application>