Be a Supporter!
dELtaluca
dELtaluca
  • Member since: Apr. 16, 2004
  • Offline.
Forum Stats
Member
Level 20
Blank Slate
AS:Components Oct. 18th, 2005 @ 01:28 PM Reply

AS:Components

This tutorial will cover creating the component .fla and .as class file

Availability:
Flash MX 2004
Flash 8

AS:Main

-------------------

the .fla file

1)open a new .fla file and save it with the name of your component
2)create a new movieclip on the stage with linkage for action script (but not export on first frame) linkage name should be the name of your component
you must also set the AS2.0 class (explained in step 6)
3)on the first frame of the movieclip draw a white box 100*100 and convert to a movieclip named bounding_box : give an instance name of bounding_box
4)on the first frame actions add stop();
5)add a new frame on the second frame:

In this frame is where you will place all the movieclips needed for the component:
each movieclip must be set for linkage to actionscript and not export in first frame (it is not needed since the movieclips are inside of the first movieclip)
each linkage name should have a unique pre-fix so that it wont clash with any other linked movieclips the user might use:

for example you may use a prefix like abcd_ or whatever

6)In the library right click on the first movieclip and go to 'Component Definition...'

In here you must set a few things:

#the first is the 'AS 2.0 Class' variable - this is the name and directory of where the class file is in relation to the .fla
(if it isnt in the same directory then you must specify the directory but for some reason, you dont use '\' to seperate like classfolder\classfile for some reason you use a '.' instead so that 'classfolder\classfile' becomes 'classfolder.classfile' (note it does not have .as on the end)

#tick 'Lock Parameters in Instance' and 'display in components panel' and set 'tooltip text' to the name of your component

#at the top is the parameters table, here you must set all the extra parameters you're component is using (not neccesary)

-------------------

the .as file

i recomend that if you have no idea what a class is that you read a tutorial on OOP either from AS:Main or from elsewhere

first off:

1) open a new .as file and save it with whatever name you gave and in what ever directory you gave in relation to the .fla in the 'Component Definition...'
NOTE THAT THE CLASS FILE NAME MUST BE THE SAME AS THE CLASS NAME AND CLASS FUNCTION OF THE CLASS FILE

2) for tutorials sake i am going to call the class 'RainyDays' (dont ask why its the first thing that came to my head)

class RainyDays extends mx.core.UIComponent
{
}

there are 4 main functions a component class must have

function RainyDays() {} (this can just be left empty if you want but it must be included)

private var bounding_box:MovieClip;
private function init():Void
{

super.init();
bounding_box.swapDepths(1);
bounding_box.removeMovieClip();
/*
create and set whatever vars you may want to set when initialized
*/

}

private function createChildren():Void
{

/* here is where you attach all your movieclips to the component from the first stage */

attachMovie("abcd_hello","mc_hello",1);
attachMovie("abcd_happy","mc_happy",2);

/* this is also where you should place all the code that may be applied to these movieclips - any button code etc */

}

all variables and mc's must be declared in the class i.e.

private var mc_hello:MovieClip;
private var mc_happy:MovieClip;

finnaly:

private function draw():Void
{

/*this is the main visual function where everything is placed and scaled and is extremely important*/

/*a useful part of components is that you can resize them, by resizing the component, we must scale and re-place all movieclips inside*/

/*we can do this by accessing width and height which are two auto-declared variables storing the width and height of the component movieclip*/

var min:Number = Math.min(width,height); // these are 3 useful variables for scaling and position movieclips correctly
var offsetX:Number = (width-min)/2;
var offsetY:Number = (height-min)/2;

mc_hello._width = mc_hello._height = min;
mc_hello._x = offsetX;
mc_hello._y = offsetY;

mc_happy._width = mc_happy._height = min/2;
mc_happy._x = offsetX+min/4;
mc_happy._y = offsetY+min/4;

}

another standard function to have in a component is setSize(width:Number,height:Number) for setting the size of the movieclip through AS

public function setSize(w:Number,h:Number):Void
{
__width = w; //note how its __width and not width or _width
__height = h;

invalidate();
}

invalidate() is an important function call which basicly simply calls the draw() function along with other hidden functions from UIComponent

//////

so alltogether so far, the class file looks like this:

class RainyDays extends mx.core.UIComponent
{
private var mc_hello:MovieClip;
private var mc_happy:MovieClip;
private var bounding_box:MovieClip;

function RainyDays(){};

private function init():Void
{
super.init();
bounding_box.swapDepths(1);
bounding_box.removeMovieClip();
}

private function createChildren():Void
{
attachMovie("abcd_hello","mc_hello",1);
attachMovie("abcd_happy","mc_happy",2);

mc_happy.onPress = function()
{
_parent.mc_hello._visible = false;
}
mc_happy.onRelease = function()
{
_parent.mc_hello._visible = true;
}
}

private function draw():Void
{
var min:Number = Math.min(width,height);
var offsetX:Number = (width-min)/2;
var offsetY:Number = (height-min)/2;

mc_hello._width = mc_hello._height = min;
mc_hello._x = offsetX;
mc_hello._y = offsetY;

mc_happy._width = mc_happy._height = min/2;
mc_happy._x = offsetX+min/4;
mc_happy._y = offsetY+min/4;
}

public function setSize(w:Number,h:Number):Void
{
__width = w; //note how its __width and not width or _width
__height = h;

invalidate();
}

}


using ShamelessPlug; NapePhysicsEngine.advertise();

BBS Signature
dELtaluca
dELtaluca
  • Member since: Apr. 16, 2004
  • Offline.
Forum Stats
Member
Level 20
Blank Slate
Response to AS:Components Oct. 18th, 2005 @ 01:30 PM Reply

the next important thing: how do re access and change the parameters we set in the 'Components Definition...'

first we need to declare the variable we will be using to store the parameter, for example i am going to use a parameter from Components Definition named rainyness:

in the class file i am going to name the variable

private var _rainyness:Number;

next we need to give flash some functions for dealing with it:
we need to add an Inspectable tag for each parameter followed by a set and get function

[Inspectable(defaultValue=10,type=Number)]
public function set rainyness(r:Number):Void
{
_rainyness = r;
invalidate();
}
public function get rainyness():Number
{
return _rainyness;
}

the inspectable tag to me seems to be going againts the AS syntax, but nvm; there are 3 things you can set in the Inspectable tag
first is defaultValue: this is the defaultValue giving to the parameter
second is type: this is the datatype for the parameter whether it be Number, String or whatever
third is enumerator: this is used when the datatype is Array and is a quote-enclosed comma-delimited list

for example

[Inspectable(type="Array",enumeration="a,b
,c,d,e,f,g")]

When you update the parameters for a class by adding, removing, or modifying [Inspectable] metatags, you must open the Component Definition dialog box and click OK again for Flash to update with the new information.

//

the set and get functions: these are simple functions flash calls upon when accessing or setting parameters from flash in AS
you do not actually have to call a function to access or set these parameters, all the user needs to do is this:

componentinstane.rainyness = 10; (this will call the set function)
var a:Number = componentinstance.rainyness; (this will call the get function)

/////

pretty much last of all are events: (the use of listeners by the user)

events are very simple to add:

all you need to add in your class to register an event that the listener the user creates will pick up on is this:

dispatchEvent({type:"raindrop",rainmolecul
e:10}); for example, this will call the listener with the event raindrop with the included rainmolecules variable in the eventObject sent with the event to the function as a parameter

ie. t.raindrop = function(a:Object){ trace(a.rainmolecule) };

you must also add this line of code into the init() function to enable events

mx.events.EventDispatcher.initialize(this)
;

the class will also inherit the addEventListener etc.. functions

///

-------------------

the last thing which isnt important but looks nice is one last metatag which goes outside of the class
this metatag is a reference to a .png image to be used as your component icon in the Components tab
the .png file must be 10*10 pixels

[IconFile("rainydaysIcon.png")]

so altogether the class now looks like this:

[IconFile("rainydaysIcon.png")]

class RainyDays extends mx.core.UIComponent
{
private var mc_hello:MovieClip;
private var mc_happy:MovieClip;
private var bounding_box:MovieClip;

private var _rainyness:Number;

[Inspectable(defaultValue=10,type=Number)]

public function set rainyness(r:Number):Void
{
_rainyness = r;
invalidate();
}
public function get rainyness():Number
{
return _rainyness;
}

function RainyDays(){};

private function init():Void
{
super.init();
mx.events.EventDispatcher.initialize(this)
;
bounding_box.swapDepths(1);
bounding_box.removeMovieClip();
}

private function createChildren():Void
{
attachMovie("abcd_hello","mc_hello",1);
attachMovie("abcd_happy","mc_happy",2);

mc_happy.onPress = function()
{
_parent.mc_hello._visible = false;

_parent.dispatchEvent({type:"raindrop",rai
nmolecule:_parent._rainyness}); //lol such a stupid component this is ^^
}
mc_happy.onRelease = function()
{
_parent.mc_hello._visible = true;
}
}

private function draw():Void
{
var min:Number = Math.min(width,height);
var offsetX:Number = (width-min)/2;
var offsetY:Number = (height-min)/2;

mc_hello._width = mc_hello._height = min;
mc_hello._x = offsetX;
mc_hello._y = offsetY;

mc_happy._width = mc_happy._height = min/2;
mc_happy._x = offsetX+min/4+_rainyness;
mc_happy._y = offsetY+min/4;
}

public function setSize(w:Number,h:Number):Void
{
__width = w; //note how its __width and not width or _width
__height = h;

invalidate();
}

}

--------------------

compiling our component:

to compile the component we simply right click on the first movieclip in the library and click export SWC file

to test the component you can simply test the movie
or you can convert to compiled clip to test other aspects:

i will probably make another AS thread on creating MXP files and creating xml files for syntax highlighting and documentation etc (probably, im not promising anything)

i know this is a pretty big tutorial but hopefully ive explained everything clearly enough: if your component isnt working, i would first check linkage names and variables in the components definition first making sure they are right before going to the AS file:

here is a sample .zip with the .as and .fla file of the RainyDays component (haha such a useless thing it is) [in mx2004 format for you losers that dont have flash 8]


using ShamelessPlug; NapePhysicsEngine.advertise();

BBS Signature
JPI
JPI
  • Member since: May. 9, 2005
  • Offline.
Forum Stats
Member
Level 21
Blank Slate
Response to AS:Components Oct. 18th, 2005 @ 01:31 PM Reply

Beyond me, but useful, if i knew how.

And some simple actionscript i picked up from the code.

Thanks


SIG YOINK!

BBS Signature
Toast
Toast
  • Member since: Apr. 2, 2005
  • Offline.
Forum Stats
Member
Level 09
Blank Slate
Response to AS:Components Oct. 18th, 2005 @ 01:46 PM Reply

Pretty damn useful, I never bothered to use components. I discovered it gives quite a professional look to games/ interactive smthingies.


BBS Signature
Inglor
Inglor
  • Member since: Jan. 26, 2003
  • Offline.
Forum Stats
Member
Level 17
Blank Slate
Response to AS:Components Oct. 18th, 2005 @ 01:49 PM Reply

you can make components in MX too...

dELtaluca
dELtaluca
  • Member since: Apr. 16, 2004
  • Offline.
Forum Stats
Member
Level 20
Blank Slate
Response to AS:Components Oct. 18th, 2005 @ 02:06 PM Reply

At 10/18/05 01:49 PM, Inglor wrote: you can make components in MX too...

well yeah, but not with this method, the way in MX is just too damn confusing, also the components code is not protected


using ShamelessPlug; NapePhysicsEngine.advertise();

BBS Signature
Sir-Davey
Sir-Davey
  • Member since: Jul. 9, 2001
  • Offline.
Forum Stats
Member
Level 19
Blank Slate
Response to AS:Components Oct. 19th, 2005 @ 10:41 AM Reply

Excellent tutorial!

I've been looking for one for ages. Time to make a button component, and completely revamp my ArtChat interface ^^


BBS Signature