Search Box

Google
 

Wednesday, October 24, 2007

Organizing your ActionScript code.

Well when it comes to actionscript projects, one stops to think and wonder how do I start ? Wow that's a very elementary question but also it is very important and fundamental.

One approach is to open flash IDE and start writing the code like hell and pride yourself with the speed with which you complete, and end up being the most most happiest person in this whole world. Days pass by and one day something new to be added turns up for the happiest project you did once before only to make you feel annoyed and irritated at the end of the day. Remember writing code would be like getting married to a girl due to infatuation where you enjoy the initial phase but regret later. Whereas on the contrary if things had been organized and are in the right places with proper framework will result in something that can be better maintained and a good rapport will always exist between you and your code(wife). Forget about maintaining it yourself but anyone who takes it later will load you with lot's of blessings (in real life scenario this does not apply to my example).

Have you decided about your attitude towards writing code ? If yes please proceed further, else you always have time to take a decision and make a choice out of yourself.

Whatever I am going to explain hereafter will strongly pertain to AS3 and still will be applicable to AS2 also. I will not be explaining about frameworks or design patterns for I myself lack a lot in that area and lot to be learned is still pending. Instead what you will see in this tutorial is some of the techniques I have been following till now in my ActionScript career.

 

 

The folder Architecture :::::::::::::::::::

Before you start with a project ensure to maintain proper folder architecture. A good developer will always do this. Ensure that you have the following folders for sure in your project folder.

 

com - Folder consisting of your class files.

src - Folder containing your source FLA file(s).

bin - Contains the output file (subfolder's Release || Debug).

assets - Contains the graphic assets required for designing your flash project.

includes (If as2 ) - Folder containing the necessary include files (Generally there is only main.as).

 

Folder "com" explained

Usually this folder contains a folder named "yourcompany" which in turn will contain subfolder named "yourprojectname" and subfolders with the following names.

 

main - The main controlling class file Main.as is present here.

display - Class files used for linking to display objects or referenced via linkage id are created here.

components - Class files used for your custom components are created here. (example : CustomScrollbar.as etc., )

utils - Class files that are written to do some utility operations (example : MyMath.as, Logging.as etc.,)

 

With this you will now be able to sort out and will be able to design your application framework in an even better way.

 

Some example classes are written below for your better understanding.

 

Display class example :

 

package com.yourcompany.yourprojectname.display

{

public class YourClassName extends MovieClip
{
    public function YourClassName ()
    {


    }
}

}

Component class example :

package com.yourcompany.yourprojectname.component

{

public class YourComponentName extends MovieClip
{
    public function YourComponentName()
    {


    }
}

}

Main class example :

This differs a little bit based on the version you are currently targeting. The immediate below one is an example of AS3 and the next is for AS2 

 

AS3:::::::::::::::

package com.yourcompany.yourprojectname.main

{

public class Main extends MovieClip

{
    public function Main()
    {


    }
}

}

 

AS2:::::::::::::::

class Main

{

    private var mainmovie:MovieClip;

  
    public function Main(targetScope:MovieClip)
    {

         mainMovie = targetScope;

    }

}

 

Utils class example :

package com.yourcompany.yourprojectname.utils

{

public class YourUtilClassName

{
    public function YourUtilClassName()
    {


    }
}

}

Fine I accept the way you have presented and will attempt to try this. But tell me how do I proceed after this ?

That was a good question you asked now, get back to the folder architecture mentioned above for a flash project. Supposing you are using AS3 then you just need to set the Main.as as the document's class with the path com.yourcompany.yourprojectname.main.Main.as. Once again if you are using AS2 then comes the role of the "includes" folder where you write a small main.as and place it in this folder. The content of the main.as file would be something like as shown below.

 

import com.yourcompany.yourprojectname.main.Main;

var main:Main = new Main(this);

Save this file and include it in the first frame of the main main using :

#include "includes/main.as"

 

Now try compiling the file and lo the compile has failed ! But why ? I don't want to realize now that after all this amount of reading this has resulted in an error. Please don't tell me that.

 

Patience my friend I did not want you to anticipate errors and the reason for this is just wanted you to wonder and know the concept of Document Class Path setting. If you remember correctly we have put the fla inside a folder named "src" and the files are above one level from the path of the flash source file. So when the movie is compiled it starts to look for the class files and the included file and hence it panics for it expects to find the folder "includes" and "com" inside "src" itself. To clarify all about this we will now look at Publish Settings.

 

Publish Settings ::::::::::::::::::::::

 

Document Class Path :

Since we wanted to maintain the architecture of the folder intact we have kept the files in their respective directories. So in order to compile the class files along with the included "as" files we will add an new path using the PLUS button and enter ".." to Document Class Path in the Publish Settings for swf. Screenshot available for more clarification.

 

 

Publish Location Setting. Since the outputs generally go to the bin folder decide if the version is a release version or the debugger version and point them to the respective folders (release/debug) inside bin folder.

 

That's all is needed to be known for a effective project maintenance and the rest lies upon your rational and creative intelligence. See you all in a short time and till then bye.

 

Regards,

Ashok Srinivasan.

Thursday, October 04, 2007

AS3 Migration - XML PARSING.

Something is better than nothing. This is a thought that runs into the mind of a Flash Developer working on a project that requires a lot of XML based data handling. But now that is not the case anymore, with the new AS 3.0 comes a powerful XML parser that implements E4X standards. With this standard being implemented in AS 3.0 now we don't have to go through the pain of parsing a known XML format anymore. What I mean is  no more heavy loops and inner loops to access a childnode at a deeper levels. But still do not worry for the legacy XML AS 2.0 classes have been moved to flash.xml package and retained. So if you still want to use the old style XML class still you can have it from this package. My sincere recommendation would be to get used to the new one and discard the old fashion of parsing the XML.

When I said E4X has been implemented what do I exactly mean by that ? In ActionScripting 2.0 while dealing with XML we had to refer to children nodes and their nodes values using index positions (numbers) and never had a way to find an element in a document by using the name value. Meaning we were not able to search XML documents using name values but had to use integers as the index position for locating XML nodes. This resulted in cumbersome loops and logics to access a particular childnode that was lying deep into the rabbit hole.

 

For example consider the below family tree represented in XML.

<GrandFather>
    <children>
       <Ram>
          <children>
              <Andrew/>
              <John/>
              <Josephine age=21 isSingle ="single" sex="girl" beautiful="true"/>

           </children>
      </Ram>
      <Rahim>
         <children>
             <David/>
             <Celine/>
             <Paul/>
             <Mary age=24 isSingle = "married" sex="girl" beautiful="true"/>
         </children>
     </Rahim>
  </children>

</GrandFather>;

 

So the XML is all about some Grandfather's family. The children node clearly shows the number of sons he had under the node name children. Now further penetrating into his children nodes we understand more of his children's family and about their offspring's. Ok now let's say I am interested about the family of his first son "Ram". And to enquire about Ram's family details present in the XML using AS 2.0 would be done as shown below.

 

AS 2.0 ::::::::::::

var xml:XML = new XML('<GrandFather>

                             <children>

                                 <Ram>

                                    <children>

                                         <Andrew/>

                                         <John/>

                                         <Josephine age=21 isSingle = "single" sex="girl" beautiful="true"/>

                                   </children>

                                 </Ram>

                                 <Rahim>

                                    <children>

                                       <David/>

                                       <Celine/>

                                       <Paul/>

                                       <Mary age=21 isSingle = "married" sex="girl" beautiful="true"/>

                                   </children>

                                 </Rahim>

                             </children>

                         </GrandFather>');


xml.ignoreWhite = true;


trace(xml.firstChild.firstChild.firstChild.firstChild.childNodes
);

 

So in order to know about Ram's family we have to start from his grandpa as a reference and go all the way using the firstChild property (or childNodes[0]) for four levels and finally ask for the childNodes property to know about Ram's Children.

Now seeing that Ram's third child is a girl whose name is Josephine (nice name isn't it ?) with age being 21 and also beautiful property being true, I would like to know if she is single and hence see if I can marry her(her attribute claims that she is beautiful). Let's see how I can message her in AS 2.0 for marrying her if her status is single, for I don't want to be beaten by her husband incase she is married already.

 

var josephine:XMLNode = xml.firstChild.firstChild.firstChild.firstChild.childNodes[2];

if(josephine.attributes.isSingle == 'single')
{
    trace('Josephine will you marry me ?');
}
else
{
    trace('Convey my regards to your husband');
}

 

Without bothering about my what happened to my proposal let's get back to the tutorial and see how the above process can be done in AS 3.0.

 

AS 3.0 :::::::::::: 

var family:XML = <GrandFather>
                    <children>
                        <Ram>
                            <children>
                                <Andrew/>
                                <John/>
                                <Josephine age="21" isSingle="single" sex="girl" beautiful="true" />

                             </children>
                        </Ram>
                        <Rahim>
                            <children>
                                <David/>
                                <Celine/>
                                <Paul/>
                                <Mary/>
                            </children>
                        </Rahim>
                    </children>
                </GrandFather>;

 

trace(family.descendants('children')[1].children());

var josephine:XMLList = family.descendants('Josephine');

if(josephine.attribute('isSingle') == 'single')
{
    trace('Josephine will you marry me ?');
}
else
{
    trace('Convey my regards to your husband');
}

 

Don't you think this is much easier than the previous one? The concept reference by name is actually good. Still one can access the childnodes using index positions too but the thing is it is more easy to traverse through a XML using String based search words rather than indexes. 

Did you see the vast leap in XML processing ? I would personally say that is really a great thing Adobe has introduced into AS 3.0. For I see no more nightmares with monster loops having big i,j,k..... claws to fight through a XML and its childNodes.

Hope the above tutorial on XML was useful. More is yet to come.

 

Regards,

Ashok Srinivasan.

Thursday, September 13, 2007

AS 3 Migration ..... Part 2

As each day is progressing with AS-3, my life has become really interesting nowadays. Today we will be seeing the next step's we will be taking in learning more about AS-3 migration. To do that we will start with a small hello world application. By this way we will learn almost all  of the basic aspects of Flash/AS 3.0 and by the way to do this exercise you need to have Flash CS3 installed in your machine.

Before starting with the new HelloWorld application, we have a small home work to be done initially. Create a new folder in a location and with name of your convenience and inside the folder you created just now, create a new folder named "Hello World". Once that is done then navigate inside the created folder and create a subfolder named "com". Inside "com" create another subfolder named "learn". Don't get angry with me but for the one final time create two folders named "as3" and "Main" as subfolder's inside the last created folder "learn".

Now if look at  your current screen it should look like the one below(except for the three red circles which was made by me using mspaint to show the path and the two subfolders created for reference).

 

Thats it for now and run the Flash IDE, after it has initialized completely do select "File" -> "New". From the options select "Flash File(ActionScript 3.0)" and click "OK". The screenshot is attached below for your reference.

 

After creating the Actionscript 3.0  type File click on the stage and create two objects as follows

1) Dynamic TextField  - instance name "$dyn".

2) Simple Button - instance name "$btn" .

 

Now click an stage area and open the properties panel(shortcut ctrl+f3). Now the property panel is open type com.learn.Main.Main in the Document Class field. See screenshot below.

 

 

 

Do not try to compile for we have to add the class files now. Still you wish to know what could have changed in the error messages go ahead and try it.

After all the above steps are completed hit Ctrl+N or create a new ActionScript File from the New Document window just like the way you created a new flash file sometime before but select ActionScript File (which would be probably the sixth item). Upon successfully opening an empty ActionScript file copy and paste the code below. see screenshots first.

 

 

package com.learn.Main
{
    import flash.display.MovieClip;
    import flash.text.TextField;
    import flash.events.MouseEvent;
    import flash.display.SimpleButton;
    import com.learn.as3.HelloWorld;
    public class Main extends MovieClip
    {
        private var hWorld:HelloWorld;
        public function Main()
        {
            init();
        }
        private function init():void
        {
            trace('I N I T');
            hWorld = new HelloWorld();
            $dyn.text = hWorld.sayHello();
            $btn.addEventListener(MouseEvent.CLICK,releaseAction);
        }
        private function releaseAction(e:MouseEvent):void
        {
            trace('onRelease : '+e.target.name);
        }

   }
}

Finished pasting the above code ???? Now save it in the name "Main" under the folder com->learn->Main->Main.as. What we have done now is an ActionScript class has been associated with the FlashDocument itself. have you ever remembered this being possible in the previous versions ? what we have been doing earlier was that we wrote an class file and associated the main timeline as an parameter to AS2.0 class file. But now the Flash File itself can be associated with an Custom Class File. isn't this great ?

We are almost 70% done for the tutorial to be completed. The one final thing you have to do is create another ActionScript Class just like the way you created Main.as and paste the below code in that. Save the file under the folder com->learn->as3 with the name HelloWorld.as.

 

package com.learn.as3
{
    public class HelloWorld
    {
        public function HelloWorld()
        {
        }
        public function sayHello():String
        {
            return "Hello World";
        }
    }
}

Done pasting the second code? Now get back to the fla file and save it under the folder Hello World with the file named as "HelloWorld.fla". Now there should be a flash source file "HelloWorld.fla"(you will see file name extension ".fla" only if you have enabled show extensions setting in windows) and a folder (which we created initially) named "com" inside the folder HelloWorld. To avoid confusion and for having a clarity see screenshot below.


Now that everything is in place and the only step remaining is to compile the flash file we have created. Doing this will generate the swf file named "HelloWorld.swf " without any errors if you had copied and pasted the code and saved them with the appropriate names and at correct location specified above. The output of the swf  is attached as a screenshot below.

But still if you wish to know what happens when the button is clicked you need to either run it from the Flash IDE or have some good logger tools like afterthought or Flash Tracer plugin for firefox.

Thats it for now and we will in less time see what the chunk of code written for this tutorial does.

 

Regards,

Ashok Srinivasan.

Tuesday, September 11, 2007

AS3 Migration......

 

Hi folks,
it's been a long time once again. Latest news at my end is that i have started working on AS3 and i need to say at this point that it really great and cool. With the new AVM2 (adobe virtual machine version 2) powering players above 9 one can really create wonders double/triple the times over the previous versions.
Initially i was a bit skeptical about getting into AS3 for my current projects i am working on are so Himalayan such that it would take a lot of time and energy to really convert it to support flash player9. Moreover i felt it was a great paradigm shift for someone like me for AS3 migration. Guru's out there have really started rocking with AS3, while a lot of children like me sitting here keep wondering about what's the deal in the new version of flash. I was also feeling that i am not doing my homework on learning AS3 for my current projects did not spare me the time for that but luckily and also daringly i thought of starting my new project based on AS3. Though it was a great risk but still was ready to face it.
Below i have mentioned a few areas where great changes have happened.


The new Class style :::::


Whenever we wanted to have more than one class file to share the same name serving different purpose but could not have it. In As3 they have introduced the concept of package naming culture as used in JAVA(but can you tell me what in Actionscript is not like JAVA?). This serves as a way to differentiate two classes sharing the same name but serving different purposes. Look below for an example.


An example of a AS3 class file

package com.mycompany.myprojectname.purposename;
{
     import requiredclasses.*;
     public class MyClass
    {
            public function MyClass()
            {
            }

            public function doSomething():void

            {

            }
    }

}

 

 

And now after the class is being written we can as usual import the package in the timeline and instantiate the variable the usual way as we do in AS2.0

Example ::::::

import com.mycompany.myprojectname.purposename.MyClass;

var mclass:MyClass =  new MyClass();

mclass.doSomething();

   

And now as we have now seen how the classes have changed to a class way we will now look at what has happened to our onPress, onRelease, onReleaseOutside etc.,

 

Handling Events ::::::

Before dwelling deep into the details we will now look at how we assigned mouse events to movieclips and buttons the AS-2.0 way.

 

       Example AS-2.0 ::::

       var mc:MovieClip = this.createEmptyMovieClip("mc",0);

       mc.onPress = function()

       {

        trace("Hey i think a jerk pressed me");

        //output shows this message when pressed

       }

 

 Example AS-3.0 ::::::

First create a rectangle and convert it to movieclip with the library name MyMc. Below are the screenshot's for your reference.

 

 

import flash.display.MovieClip;

import flash.events.MouseEvent;

var mc:MyMc = new MyMc();

function myMcClick(e:MouseEvent):void

{

   trace("Hey some jerk pressed me");

}

this.addChild(mc);

mc.addEventListener(MouseEvent.CLICK,myMcclick);

 

So this is the way we add actions to the new version of Flash.

 

Depth Management ::::::

Yeah this is the part i loved the most with AS-3.0. From the above example's code for AS-2.0 and 3.0 you would have noticed that there are some differences in the way we work with adding and assigning actions to MovieClips. The thing is that in the new version we have been spared the job of assigning the depth. You just need to use the keyword "addChild" which is a method in any MovieClip to add a childMovieClip.

Example ::::

//to create an MovieClip from the library.

var myMc:MyMc = new MyMc();

this.addChild(myMc); 

 

So how do we remove a MovieClip we added to the stage ????

Example :::::

//to create an EmptyMovieClip from the library.

var myMc:MyMc = new MyMc();

myMc.name = ''foo';

this.addChild(myMc); 

//To remove this movieclip you have created.

this.removeChildAt(0);//where the number is the index.

//or

this.removeChild(this.getChildByName('foo'));

//or

this.removeChild(myMc);

  

Many more promising new things have come in the new version and i am at all loss of words to express it completely now. Better keep visiting my blog for there will be more updates,posts and learning's with what's new in AS-3.0.

Tuesday, July 24, 2007

Children will be Children, Flash will be Flash

Well the title itself suggests when things prove to be problematic while dealing it the natural way then we need to do some workarounds always. But at the end we find a solution. And here i present a problem that i faced while working one of the vital child of Flash and mine called as the TEXTBOX.

Assuming myself to be a dad in flash programming (not yet a dad in real life b'coz i am not a husband yet. I am still an Eligible bachelor you see...) i had to deal with this TextBox child of mine. Let me tell you his problems, he can either stuff his fonts with him by embedding or either stay using Device Fonts before going out to the world from his development home. But the former way suggests that his bag becomes heavy with each different type of font he will be supporting. Consider supporting Ten generic fonts that will be available in all the operating systems, then the process is to add 4 types of fonts in the library with normal,bold,italic, and bolditalic options seperately.

Elobrating on the process consider embedding Arial font which would result in four font items in the library with following linkage ids :

Arial - normal support with bold and italic option disabled.
ArialBold - Font with only Bold option.
ArialItalic - Font with only Italic support.
ArialBoldItalic - Font with Bold and Italic support.

And the max size for all the above embedded fonts items would be 72.

Now coming to the original count that we needed to support was 10 and hence the total number of embedded fonts we need would be (10 x 4 = 40). Can you imagine the size of your swf ? ok, here still i have the option of using RunTime shared font. After all this is done we can now rotate,scale the textboxes in our application.

Think once again is there a better solution to this ? Now being in the world where Flash7 is close to becoming history and flash 9 prevailing on all the browsers widely we now have options of rendering text in a better way.

One more time i am going to present you all a way to exploit the Bitmap Class for serving this purpose. Coming to the original requirement i just removed all the embedded fonts from the library and selected the Device Fonts as the text rendering method. But here comes the problem that i will not be to rotate and scale the textboxes in my application. Also using Device fonts ensures me no heavy stuffs to be stuffed to my TextBox child. He can be light and compact, the only time when i would face problem would be when rotating my child.

Hmmmm...... what are we going to do now ? Better would be to draw a bitmap object using the textbox, attach it to a movieclip and rotate that instead of transforming the textbox directly. So only while editing the text we need to show the textbox and once the editing is completed we display bitmap that is drawn to the updated version of the textbox with the transformation applied already.

Hope you understood how i dealt with my son and might also help you in a similar scenario.

Thursday, July 05, 2007

Being Greedy for finding WordWrap in Flash.

Hello All,

Again after a longtime here i come to talk about learning a way to find the breaking position in a Dynamic/Input Textbox. Wait did i mean "Finding Wordwrap positions in a Dynamic Textbox " ?. Yes you thought right. I am here to discuss an algorithm to find the positions wherever Wordwrap happens to appear in a Dynamic Textbox in flash. But beware it is very greedy and quite possible that it might eat your processor. Still check out wikipedia on wordwrap and you will find "greedy" type algorithm to be one of the ways to find wordwrap positions in general.

Okay let me not take this post further by posting code which again will not ensure that all of us might understand it.

But before you proceed brush yourself about the TextFormat class and especially the "getTextExtent" method. I hope you would have guessed what i am trying to do. Yeah, Inorder to find the breaking positions within a TextBox this method is sufficient enough to find the answer/solution.

Wait does flash not have a method to do this ? i would say a BIG NO. For that instance not only flash but any application would not have a method to find the wordwrap position. Do you know the reason why ? Since the wordwrapping is handled by the applications UI Algorithm and does not insert nor append any line formatting characters such as "\n" or "\t" etc., at the breaking point so that we can break the text using the split method using these characters.

Instead the solution that worked for me was getting the current TextFormat of the textbox we need to find wordwrap positions using getTextFormat(). Using this textformat we take the string content of the textbox and then using "WHILE" loop i move the character index one by one and store it in a temporary string "tempString" thereby also checking simultaneously the width in pixels which i get by applying MyTextFormat.getTextExtent(tempString) to see if the textWidth returned has not crossed more the width of the textbox for which we are currently checking.

Once if i find the condition of tempString width being more than the currentTextBox Width is successfully satisfied, i remove that part of the tempString from the original string using :

originalString = originalString.substring(tempString.length-1,originalString.length);
someArray.push(tempString.substring(0,tempString.length-1));
// REmember that the length has exeeded so the breaking point is the length -1 ;

//Now clear the tempString

tempString = '';


This process is carried until after all the characters are removed from my original string meaning (originalString == ''").

After this algorithm has finished running i would end up with an array containing strings. From the array length once can find the total number of lines and also the way the lines have been split up in a textbox with any font, size etc.,

Hope you understood the intention and its solution posted in this blog.

Regards,

Ashok Srinivasan.





Thursday, March 08, 2007

Adding and removing Strings in ActionScript.

It's been a long time since i was hanging around with BitmapData and now for a change i am going to write about one of the primitive datatype of ActionScript called "String". Today i am going to discuss with a story about why we should focus on using methods that have been shipped with the native classes rather than writing flash loops and achieve the same.

Today my colleague came rushing to me to show his new prototype he had written for String class. The reason he came to me was that i am known for optimizing codes(do not blame me for this) and hence he wanted me to take a glance of his code and suggest necessary modifications wherever applicable. But to his dismay and disappointment slowly his face started to grow smaller and smaller as we sat down to modify his code (he must have been thinking "oh my god why did i ask this guy anyway).

Still wondering what am i talking about ? Let me take the pleasure of telling you what happened. In one of the application my friend was developing he had a requirement of adding and removing strings. The scenario was like this, a word is passed to a custom method written as a prototype as an argument which needs to be added to the existing string if it does not exist. Else if the particular word already exists then remove it.

hmmmmm, nice requirement i would say and below is the code written by my friend .




String.prototype.appendAndRemove = function(remStr:String):String
{
var tempArr:Array = this.split(remStr);
trace('arr : '+this.indexOf(remStr));
if(tempArr.length >=2)
{
var tempArr1:Array = this.split(remStr+' ');
this = '';
for(i=0;ilength;i++)
{
this += (tempArr1[i].length !=0)?tempArr1[i]:'';
}

}
this += (tempArr.length != 2)?remStr+' ':'';s;
return this;
}


Looking at the code anybody can understand what the developer had intended to do and moreover the name itself suggests sharply about its use. okay let us ask achilles what he has to say about this.

I would say we could have avoided the loop that's been used in the code and rather used the .join method instead. Below is my version of code which does the same thing as the above code and coincidentally has the same bug the above one has(find it out yourself about what the bug is).



String.prototype.appendAndRemove = function(remStr:String):String
{
return (this = (this.indexOf(remStr) == -1)?this+remStr:this.split(remStr).join(''));
}



Hey wait do not conclude i am bluffing and believe me both the version of codes literally do the same thing. If you still do not believe go ahead and check it out yourself.

Meanwhile let's meet you all in some time soon.

Regards,

Ashok Srinivasan.

Sunday, February 18, 2007

ever wanted to make a face to others ?

Subject : Face cropping in flash, irregular image cropping, cropping of irregular shapes and of irregular symmetry.

I do not know why but amongst all the new features of flash player 8, BitmapData stands out of the rest shining like DHRUVA guiding and seemingly being the solution to all image/graphic related issue in flash (those issues are now history anyway).

But i would say that BitmapData ROCKS. Few days back i was just feeling i am getting to love this class very much and wanted to mention about her again and again. The rest of the blog is all about a small application that i had developed to meet the need like cutting a face or cutting a portion of the image using flash. I mean basically think it as an application/tool for cutting the beautiful face of yours and adding it to the headless cartoon with Superman's body. I know you have already suspected that i am upto some mischief. Maybe but even though it is so, but the end result is a tool being developed with the power of flash and php.

First of all i would like to thank "SEPIROTH" for his wonderful class tha does the saving of BitmapData and sending it to php safely. Hei man your class really rocks.

Next coming to the flash part (kudos to ME), which is the easiest part than php. Here is the place where some points are added to the image and in turn the points are interconnected with the lines and filled duly thus making a shape of irregular symmetry. No problem i have at all the times keep monitoring the individual points for their x,y coordinates and thus using them to compute the rectangle formed by these collection of points.

Do not get overwhelmed at this point for once you see the output you will start to understand howExaggerating i was in this summarisation. But still if you still wish to proceed by reading further read on, else jump to the bottom where there is a link pointing to the location of the files. No problem at all jumping and do not feel bad.

But before jumping to the link make sure you have all this in your system to test the tool !

PHP server with GD library installed.


Note: To install GD library (if not installed, make sure you take a backup of you php.ini before you make any changes.), open you php.ini file and remove the ';' symbol before the line ";extension=php_gd2.dll". This is for windows and i dont know what it looks like to enable GD library in php on linux box. i guess it should be "php_gd2.so" instead of ".dll".


Link to the image cropping files.


Link to the screenshot of the tool

(incase you are finding it difficult to download the file then mail me : ashok_srinivasan2002@yahoo.com. i will see to that i will be in a position to sort it.)


Hope you enjoy and use this tool for your wildest uses and adventures.

Regards,

Ashok Srinivasan.

Friday, February 16, 2007

A Delegate Action.

So what does Delegate has got to do with ActionScript ? Yes it means a lot when it comes to Actionscript classes and scope management. Scope issues are one of the fundamental issues when it comes to ActionScript classes.

Let me take the pleasure of discussing about Delegate class today. But wait where does Delegate come from ? She comes from mx.utils.Delegate. Meaning there is a folder 'mx' containing lots of flash goodies classes among them we find a branch 'utils' which holds the fruit called 'Delegate'. Why do i need to praise so much will be understood by you shortly.

Consider the following script :



//in the main timeline we have a movieclip with instance name "$mc".


var This:MovieClip = this;

this.$mc.onPress = function()
{
trace(This);//traces _level0;
}


Guess that code was very elementary to be understood and hope does not require any explanation. Things are working fine is assumed based on the trace message of "_level0" which should be seen when rendered.

But this is not the case when it comes to classes. For example consider the next example :



//Now in the main timeline using the movie created with the example 1.

var This:MovieClip = this;
var te:Test = new Test($mc);

//For the class 'Test' copy the code below, create a new .as name it "Test" and paste the code.


//The class defintion starts.

class Test
{
var movie:MovieClip;
var This:MovieClip;
public function Test(mc:MovieClip)
{
movie = mc;
This = movie._parent;
movie.onPress = function()
{
trace(This)//traces 'undefined';
}
}
}


Ctrl + Enter and click the movieclip on the stage.Now did you see what happened, it would have been a message 'undefined'. So how are we going to handle this forms the rest of the story with the introduction of our Delegate character as the hero.

Okay now we will do some slight modification to our "Test" class with the help of Delegate and see what happens.




//The class re - defintion starts.


import mx.utils.Delegate;
class Test
{
var movie:MovieClip;
var This:MovieClip;
public function Test(mc:MovieClip)
{
movie = mc;
This = movie._parent;
movie.onPress = Delegate.create(this,function()
{
trace(This)//traces '_level0';
});
}
}





Now on ctrl+Enter and triggering the press action of the movieclip displays a message "_level0" meaning the code was successfully doing the right thing. hmmm can i know what has happened to the new version of 'Test' class ? It was the 'Delegate' class who was taking the pain of mapping the variables of the class within the scope of the $mc's onPress action. B-e-a-utiful isn't it ?

The 'Delegate' class comes to the rescue for scope management while writing in classes.

As a bonus i wish to specify a hack for the Delegate class but i am stopped to make you wonder for what the bonus could be. If you start using Delegate class, soon you will come to a point you will be struck. Then at that time come back and earn your bonus. Till then happy sailing with Delegate class.


Regards,

Ashok Srinivasan.

Wednesday, February 14, 2007

Cloning is illegal , but not for FLASH OBJECTS..........

Its been really a controversial topic. "CLONING" was a buzz word that started the dawn of the era where Biotechonology was seen by a common man. Ask Michael Crichton and he would tell you scores of information about it in the form of stories. Dolly was the first cloned living being. Then there were protests, controversies and conspiracies following.

Do not worry by reading this and learning to Clone an Object or Array will not end you up in Jail, for cloning in ActionScript is not controversial or understanding it is like a grasping a big conspiracy theory.

But before that let us understand why do we need to clone ??? yeah that was a great question and i see a reason why you should read the rest of the story. The real reason for why cloning can be best understood by the following example :

Example 1 :



//in the main timeline

var num1:Number = 20;

var num2:Number = num1;
trace(num1);//traces 20
num2 = 50;
trace(num1);//traces 20 again;


Did you see what happened?
1)we created a variable num1 with a value 20.
2)Again we created a variable num2 and pointed it to num1.
3)Traced the value of num1 and it was 20
4) changed the value of num2 to 50
5) Traced the value of num1 and it was still 20.

I hope you would have understood what i am meaning by this. Once again consider the following example.

Example 2:



//In the main Timeline

var obj1:Object = new Object();
obj1.name = 'Ashok';
obj1.age = 24;

var obj2:Object = obj1;

trace(obj1.name);//traces Ashok;

obj2.name = 'Srinivasan';
trace(obj1.name);//traces Srinivasan.



So what happened here. We did the same thing that was done in Example 1, but the difference was that first example was dealing with numbers and the second one was dealing with objects. In the first one it was "copying of the value operation" and in the second one it was "pointer operation" meaning it does not create a copy and store in the new variable but instead points the first object "obj1" to the new name "obj2". Coincidentally this is the same case when we do it with Arrays. Luckily we have the "slice" and "splice" methods which can get us a copy so as to leaving the choice to us for creating a copy or pointer for an Array. But there is not a method that gives us the choice of creating copies.

Now how can this be solved ? How can i make a copy for an object and not create a pointer instead. ?

The fundamental principle is to use the "for in " loop method. But how do we clone if there are objects inside object ?

Accidentally when i was searching for ActionScript blogs yesterday i stumbled upon a blog in the name of "Arul's blog" (link:http://www.shockwave-india.com/blog/services/as-highlight2/index.php) and there the blogger guy has mentioned about this problem which made me also to think and give a mention cum workaround solution for this problem.

Using the code in "Arul's Blog" and modifying and reducing the lines where-ever possible i am pasting the code below. Make sure to check it out.




Object.prototype.clone = function ()
{
if (typeof (this) == "object")
{
var to = (this instanceof Array )?[]:{};
for (var i in this)
{
to[i] = (typeof (this[i]) == "object") ? this[i].clone () : this[i];
}
return to;
}
trace ("Warning! Object.clone can not be used on MovieClip or XML objects");
return undefined;
};
Object.prototype.trace2 = function()
{
for(var i in this)
{
trace (i + ' : ' + this[i]);
}
}
ASSetPropFlags (Object.prototype, ["clone"], 1);
ASSetPropFlags (Object.prototype, ["trace2"], 1);
myObject = new Object ();
myObject.name = "Ashok";
myObject.gender = "Male";
myObject.age = 24;
myObject.trace2();
copyObject = myObject.clone ();
copyObject.trace2();



So what does the code do ?? i guess the code was self-explanatory.

Regards,

Ashok Srinivasan.

Monday, February 12, 2007

BitmapData II.......................

Continuing from the previous post explaining about BitmapData class and using it to cache images, i am here again to share some more information about it. Okay till now we saw how we can use BitmapData to cache images but its not the only thing we can do with it but lots and lots. Remember the days of those and before flash player 7 where when a drawing application is developed the developer takes the pain of generating the color palette himself either by actionscripting or designing the color boxes in the "timeline" itself.

And also the end user is at the mercy of selecting only the colors whatever the program(developer) provides. If i say i dont like that red color then i assure to see that red color does not exist at all in my program and the user suffering from red syndrome. Always giving the choice of colors in flash that satisfies the user was never satisfying . Now no more is the case like that with the flash player 8.

Wondering how BitmapData is going to help us in this ????? Just wait and see. This BitmapData has a method called "getPixel" with the "x" and "y" Numbers as the arguments which specifies the location of the area whose color has to be picked. Yes whose COLOR (RGB) has to be picked. This method returns the color of the pixel specified at the x and y pixel. Also there is another method called getPixel32 which returns the ARGB values meaning RGB with Alpha.

Cool isn't it ?? So gone are the days of providing hard coded color palettes where now the user can even pick the color that lies by the side of his circle, oval or square shape that he has drawn in his drawing program.


Regards,

Ashok Srinivasan.

Sunday, February 11, 2007

BitmapData.........

Hai all,

i am back after a very long long time. But happy i am back atleast now. Today we shall discuss about caching image using BitmapData class. Actually "bitmapdata" is a new class that has been introduced for flash player 8. What this class can do is enormous, but we are here to discuss today what it can do for caching dynamically loaded images.

I was always wondering how can i stop those reloading of images again and again, until i was introduced to the BitmapData class by a colleague of mine who recently discovered this. After playing around with the class for sometime an idea struck to me for solving the problem of reloading the loaded images with BitmapData class being the key. This solution ultimately gave birth to a class "ImageCache" which looks after the images loaded using it and ultimately returns a BitmapData which can be attached to the image holding movieClip using attachBitmap() method.

The content of the class goes like this :

import flash.display.BitmapData

class ImageCache
{
/**
@ varible __paths
@ description: The array that holds the path of the images loaded.
*/
private var __paths:Array;

/**
@ varible loader
@ description: MovieClip that holds the images to be loaded and cached.This is a temporary movieClip.
*/
private var loader:MovieClip;


/**
@ method ImageCache
@ description: Constructor Function.
*/
public function ImageCache()
{
__paths = new Array();
}

/**
@ method registerTempLoader
@ arguments : None;
@ access : Public
@ returns : Nothing.
@ description: Method that registers a valid MovieClip to be used for caching Images.
*/
public function registerTempLoader(mc:MovieClip):Void
{
loader = mc;
}


/**
@ method : cacheImage
@ arguments : String path , float Width, float Height;
@ access : Public
@ returns : BitmapData.
@ description : When a path is passed into the argument along with the width and height
loads the image and returns the cached image as a BitmapData.
*/
public function cacheImage(path:String,w:Number,h:Number):BitmapData
{
var index:Number = isCached(path);
if( index < 0)
{
var obj:Object = new Object();
var mc:MovieClip = loader.createEmptyMovieClip('loader'+__paths.length,__paths.length);
obj.path = path;
obj.bdata = new BitmapData((w==undefined)?100:w,(h==undefined)?100:h,false,0xcc33ff);
mc.loader = new MovieClipLoader();
mc.loader.addListener(this);
mc.loader.loadClip(path,mc.createEmptyMovieClip('loader',0));
mc.index = __paths.length;
__paths.push(obj);
return obj.bdata;
}
else
{
return __paths[index].bdata;
}

}


/**
@ method : isCached
@ arguments : String path;
@ returns : Number.
@ access : Private
@ description : When a path is passed into the argument checks from the
__paths array if the path is already loaded returns the
index of the path in the array else returns -1.
*/
private function isCached(path:String):Number
{
for(var i:Number=0;i<__paths.length;i++)
{
if(__paths[i].path == path)
{
return i;
}
}
return -1;
}


/**
@ method : onLoadInit
@ arguments : target MovieClip;
@ returns : Nothing.
@ access : Private
@ description : When an image loads successfully its parent get drawn using BitmapData.
*/
private function onLoadInit(target:MovieClip):Void
{
__paths[target._parent.index].bdata.draw(target._parent);
}
}



Okay, the class is written but how do we use it ??? Nice Question !

i had developed a image gallery using this class believe me. i will paste the actionscript that exists in the timeline of the stage as given below. But before that have two things ready in the library. one is a macromedia scrollpane and the next is create two empty movieclips with one having a linkage name "thumbHolder" and the other empty movieclip does not require any linkage ids.

Now drag the ScrollPane to the stage and name it "$spane" with the content path in the parameters field as "thumbHolder". Now drag the empty movieClip without any linkage id to the stage and name it "$main".

Then paste the below actions on the first frame of the Stage.


//Instance of the ImageCache Class.
var iCache:ImageCache = new ImageCache();

//Temporary images holder.
var imageHolder:MovieClip = this.createEmptyMovieClip('tempImageHolder',0);


//The thumbnal images holder
var galleryHolder:MovieClip = $spane.spContentHolder.createEmptyMovieClip('thumbNailholder',1);


//The main picture holder.
var mainPicture:MovieClip = $main.createEmptyMovieClip('mainLoader',0);

var width:Number = 360;//Width value - change at your will.

var height:Number = 480;//Height value - change at your will.

//The below function is the one that starts to cache images.
function cacheImages():Void
{
var ratio:Number = 360/480;
var thumbHeight:Number = 480/4;
var thumbHolder:MovieClip = galleryHolder.createEmptyMovieClip('holder',0);
for(var i:Number=0;i<19;i++)
{
var index:Number = 787 + i;
var path:String = 'images/SP_A0'+index+'.jpg';//Change this value to your custom image path
var thumb:MovieClip = thumbHolder.createEmptyMovieClip('gal'+i,i);
thumb.createEmptyMovieClip('loader',0).attachBitmap(iCache.cacheImage(path,360,480),0);
thumb.loader._width = ratio * thumbHeight;
thumb.loader._height = thumbHeight;
thumb._y = (thumbHeight+5) * i;
thumb.path = path;
thumb.onPress = function()
{
mainPicture.attachBitmap(iCache.cacheImage(this.path,360,480),0);
//mainPicture.createEmptyMovieClip('loader',0).loadMovie(this.path);
}
}
$spane.redraw(1);
}
imageHolder._visible = false;//setting the visiblity of the tempimages holder to false.

imageHolder._x = 100000;//setting the distance of the tempimages holder to a large one so we cannot see it.


iCache.registerTempLoader(imageHolder);//REgsitering the tempImage Holder as the loader for caching images.


cacheImages();//Start Caching Images.


So having restarted my blogging with the BitmapData class makes me feel a bit enthus !!!!

Thanks for reading.

Regards,

Ashok Srinivasan.