AS3: Positioning and Size problems in Sprites and MovieClips

Struggling with your Sprites or MovieClips which don’t seem to be placed in the right spot or be of the right size?

Don’t worry, if there’s something I’ve learned from Flash, it’s to distrust Flash’s own positioning and size properties.

Instead, use your own getters and setters and get your piece of mind.

import flash.display.Sprite;

public class MyCoolObject : Sprite {

private var posX:int;

private var posY:int;

private var posZ:int;

private var sHeight:int;

private var sWidth:int;

public function MyCoolObject() {

}

/* Getters and Setters */

public function set X(val:int) {  this.posX = val; }

public function get X():int { return this.posX; }

public function set Y(val:int) {  this.posY = val; }

public function get Y():int { return this.posY; }

public function set Z(val:int) {  this.posZ = val; }

public function get Z():int { return this.posZ; }

public function set Height(val:int) {  this.sHeight = val; }

public function get Height():int { return this.sHeight; }

public function set Width(val:int) {  this.sWidth = val; }

public function get Width():int { return this.sWidth; }

}

It’s a bit of overhead, but trust me, you’ll thank me later…

AS3: XML, the easy way

Haven’t been able to find a tutorial on how to make XML objects that would be worth writing about in a “XML for Dummies™” book.

So hopefully after this you’ll be able to writting XML strings like crazy 😀

XML is already part of Flash globaly, so you don’t need to import it.

To make this easier to understand, I’ll use a ComicBook as an example since I’m currently working on that project which requires the usage of XML objects.

In my project a ComicBook consists of the following:

  • Comic Object
  • Comic object contains an Array of Pages
  • A Page object contains an Array of PageObjects (Sprites… MovieClips… etc….)

Now as you could assume, all these objects are nested inside our Comic object. Using nested for-loops, you can access all the information and perform different sorts of operations.

Comic will therefor, be our main Node. A Parent of sorts.

We create our first XML object tag:

var comicNode:XML = new XML(“<Comic/>”);

People who know a little bit of XML and/or some knowledge about xHTML, will recognize <Comic/> as being a closing tag.

Infact, when we try to view the resulting string, we get this:

trace( comicNode.toXMLString() ); // –>  <Comic/>

This is perfectly normal and you shouldn’t worry yet that the output isn’t  like  <Comic><Comic/>

Later when you’ll be adding elements to the Comic Node, you’ll see that Flash will automatically adapt the XML structure to what you’re feeding it.

A really nice thing is that you can dynamically add properties to your nodes, like giving it an ID, or a Name.

For example, every Comic book I generate needs to have a name. I can do so like this:

comicNode.@name = comic.Name; // –>  <Comic name=”TheNameOfMyComic” />

As you can see, using  node.@ we can generate any attribute name we want! comic.Name happens to be a String variable in the field of my  Comic class where I store the name of it.

Now for the real work! Adding different Nodes to our Parent Node.

Because Comic  contains an Array of Pages, we need to create a For-Loop which runs through all the objects within our Array. The creation of our PageNode, is exactly the same as our ParentNode.

for (var index:Number = 0; index < comic.Length; index++) {
var pageNode:XML = new XML(“<Page/>”); // –>  <Page/>
pageNode.@id = index; //  –>  <Page id=”0″ />
……
comic.Length is simply the length of my Page Array.
Now! We add our PageNode to our ComicNode!
comicNode.appendChild(pageNode); //  –>  <Comic name=”theNameOfTheComic”>
//   –>         <Page id=”0″/>
//   –>  <Comic/>
If you understand all this, then you’ve done it!  You should now be able to easily make your own XML structures 🙂
Here’s a complete excerpt of my code so you get the general picture:
//Create XML
comicNode = new XML(“<Comic/>”); // <Comic/>
comicNode.@name = comic.Name;    //Adding attibute -> <Comic name=”theNameOfTheComic”/>
//Add the Page objects
for (var index:Number = 0; index < comic.Length; index++) {
var page:XML = new XML(“<Page/>”); // <Page/>
page.@id = index; // <Page id=”0″/>
comicNode.appendChild(page); //<Comic name=”theNameOfTheComic”>
//   <Page id=”0″/>
//<Comic/>
//Add the PageObjects
for (var index2:Number = 0; index2 < comic.getPageByIndex(index).Length; index2++) {
var pageObjNode:XML = new XML(“<PageObject/>”);
var pageObj:PageObject = PageObject(comic.getPageByIndex(index).getChildAt(index2));
pageObjNode.@id = pageObj.name;
if (pageObj.movieClip.inputField != null) pageObjNode.@input = pageObj.movieClip.inputField.text;
pageObjNode.@type = pageObj.Type;
pageObjNode.@posX = pageObj.x;
pageObjNode.@posY = pageObj.y;
pageObjNode.@posZ = pageObj.z;
pageObjNode.@Width = pageObj.width;
pageObjNode.@Height = pageObj.height;
page.appendChild(pageObjNode);
}
}

AS3: Default parameter value

In ActionScript 3 it’s possible to automatically assign a default value to parameters in a function.

Parameters with optional value should be placed at the end of the function parameter list, while all the required ones at the begining.

Parameters with default values can be ommitted. This gives us the following possibilities:

function twoPlusTwoIs (result:int = 2) {

trace( “Result: ” + result );

}

twoPlusTwoIs();    —>  2

twoPlusTwoIs(3);  —>  3

Likewise, a more plausable usage:

function enable ( val:Boolean = true ) {

someVariable = val;

}

MyFancyObject.enable();           —>  true

MyFancyObject.enable(true);     —> true

MyFancyObject.enable(false);     —> false

AS3: How to use Flash Cookies

At some point, you would like to store some data on the client side, say for example, to know if it’s the first time a user is accessing your Flash application/animation, and show him/her different content based on the data.

Just like a Web Cookie, Flash Cookies can be used. The best or evil part of it, is that Flash cookies are harder to remove. In fact, they don’t go away even if the client clears all his browser cookies. That’s because it’s the Flash Player that manages those cookies obviously.

Making these cookies is super easy:

  1. add the import:   import flash.net.SharedObject;
  2. create your cookie object (SharedObject):    var cookie:SharedObject = SharedObject.getLocal(“myFlashCookie”);

The handy thing about it, is that you can add any kind of info in it (Note that the amount of data that you can store is limited to the size that the user has chosen in the configuration of his Flash Player, normally that’s 100Kb).

Here are some handy things to know:

  • cookie.size :  See if our cookie contains anything ( 0 means we have a fresh cookie… mmmh fresh cookie…. 😀 )
  • cookie.data :  Array containing any object that we want (please not the size limitation described above)
  • cookie.data.VariableName = object :  we can add any variable name to .data.
  • cookie.data.VariableName :  if  VariableName exists, it will return the object it is containing
  • cookie.flush() :  save our cookie immediately to a file (otherwise, our cookie only exists in memory during the length of the session and not being stored on the clients machine)
  • cookie.clear() :  deletes/clears the cookie (  😦  )

Another useful thing to know is that you can call the cookie remotely.

Here’s a live example that I use,  I want to show the user a tutorial on how to use my application. The tutorial will only be show when the cookie is empty.

import flash.net.SharedObject;

public class ComicGenerator extends MovieClip {

//Our Flash Cookie

var cookie:SharedObject = SharedObject.getLocal(“ComicBookGenerator”);

var forceTutorial:Boolean = false;

//Constructor

public function ComicGenerator() {

super();

initialiseStage();

//Force Cookie Deletion

if (forceTutorial) cookie.clear();

//Is this the first time the user sees our app?

if (cookie.size == 0) {

showTutorial();

cookie.data.FirstTime = true;

}

else {

showOperatingMode();

}

}

For more information, you can go take a look at the API documentation: http://www.adobe.com/livedocs/flash/9.0/ActionScriptLangRefV3/flash/net/SharedObject.html

AS3: How to add a tiled background

  1. Drag & Drop the image you want to tile on the stage
  2. Go to the Library, you’ll see that a Bitmap has been added, change the properties of it
  3. Activate the Advanced options if it isn’t shown
  4. Select both options in Linkage, and write a Class Name,  for example “Background”

From now on,  you’ll access your image as if it were a Class.

You can now make your image and tile it like so:

var backGroundSprite:Sprite = new Sprite();
//Background Class is actually the linkage to background.jpg in de Library
backGroundSprite.graphics.beginBitmapFill(new Background(0, 0));
backGroundSprite.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
backGroundSprite.graphics.endFill();
//Add and display on stage
addChild(backGroundSprite);

Variable Length parameters

You might be aware of the fact that you can use a technique called Method Overloading.

This technique allows you to use the same method signature but with a different set of Method parameters.

Say you needed to give a different number of parameters to a function, you’d either have to implement the different methods, or make a list and pass the list to the function.

ActionScript 3 has a cool function which allows you to use just 1 method signature, and allow an indifferent number of parameters of the same type.


public static function showNumbers(… myNumbers):Number{
for (uint i=0; i< myNumbers.length; i++){
trace(myNumbers[i]);
}
}

The key to all this is the “…” infront of the variable name in the parameter. You might see it as a kind of “here are the paramteres, etc… etc… 😉 )

Using a container for objects

It’s possible to make objects belong to a certain container.

Normally, everything you put on the screen is already contained within your stage. However, you can me some objects be contained by something else.

Here’s an example of how object are contained within your stage:
Stage with loose objects

These objects have simply been added on the stage with the addChild( object ); function.

Now comes interesting part, any object can be a container for other objects. To make it simpler to understand, consider the usage of “wrapper”, or in more abstract terms, a drawer.

For example:

tf1:TextField = new TextField();
tf2:TextField = new TextField();
tf1.name = "text 1";
tf2.name = "text 2";

container1:Sprite = new Sprite();
container2:Sprite = new Sprite();

container1.addChild(tf1);
container1.addChild(tf2);
container2.addChild(tf1);