Jul 23

The Problem.

Well the problem you’re facing is pretty simple, but it can also be tricky. I had the same problem some time ago, and it pretty much ruined my day. (mainly because I rush and I don’t read the documentation, which is BAD by the way)

The Solving.

There are several reasons for which you will get an error message when trying to import a component , but if you have the feeling that you did everything right and it sill doesn’t work, this may help you lot. So, don’t forget that you have to actually drag an instance of the component on the scene from the component’s panel (Window->Components to open it) no matter if you import the component in actionscript. You can delete the component from the stage afterwards but the important thing is to have an instance on your library.

Jul 20

Introduction. Associative Arrays.

An associative array uses keys to organize stored values. That means that you can use strings instead of indexes, so that the next statement becomes perfectly legal.

[-]View Code ACTIONSCRIPT
buttons['home'] = new Button(); //buttons is an associative array
contentSprites[1] = new Sprite(); //contentSprites is an numeric indexed array

Working Example. Dictionary Class.

Although the principle behind the associative array is very simple, we usually use the numeric indexed array. However there are many scenarios in which an associative array would do the job much easier, more organized and nonetheless less cryptic for others.

But what I would really like to talk about is the Dictionary Class. The Dictionary Class is very similar indeed with a associative array but it has the great feature that it can use as indexes any objects from Movieclips to Tweens (usually the object passed as index is an instance of the Object Class, but theoretic it could be anything ).

Next is an example that shows you how and most of all why you should use the Dictionary Class in certain scenarios.

[-]View Code ACTIONSCRIPT
package  {
	import fl.controls.Button;
	import flash.display.Sprite;
	import flash.ui.Mouse;
	import flash.utils.Dictionary;
	import flash.events.MouseEvent;
 
	public class dictonaryEx extends Sprite {
 
		private const buttonsObjects:Array = new Array(
		{ label:"Home", listener:$btn1, no:0 },
		{ label:"Products", listener:$btn2, no:1 },
		{ label:"Clients", listener:$btn3, no:2 },
		{ label:"Contact", listener:$btn4 , no:3 }
		);
 
		public function dictonaryEx() {
			var buttons:Dictionary = new Dictionary();
 
			for each(var obj:Object in buttonsObjects) {
				buttons[obj] = new Button();
				buttons[obj].label = obj.label;
				buttons[obj].addEventListener(MouseEvent.CLICK, obj.listener);
 
				buttons[obj].x = buttons[obj].width * obj.no;
				addChild(buttons[obj]);
 
			}
		}
 
		private function $btn1(evt:MouseEvent):void {
			trace(evt.currentTarget.label+' pressed')//output  "Home pressed"
		}
 
		private function $btn2(evt:MouseEvent):void {
			trace(evt.currentTarget.label+' pressed')//output  "Products pressed"
		}
 
		private function $btn3(evt:MouseEvent):void {
			trace(evt.currentTarget.label+' pressed')//output  "Clients pressed"
		}
 
		private function $btn4(evt:MouseEvent):void {
			trace(evt.currentTarget.label+' pressed')//output  "Contact pressed"
		}
	}
 
}

Closer look to the example.

First, we can look at the buttonsObjects array as a model from the MVC’s terminology, a entity that holds all the data for creating visual buttons. Depending on how complex the buttons are the buttonsObjects array can hold more complex objects. For this example, I choose to use only three properties label, listener, no (the label is the text that will show up on the button, the listener is the function that will be called when the mouse click ocurs and the no is the index of the button counting from left to right). In the dictonaryEx constructor we create a visual button using the Button Class for each object in the buttonsObjects array.

I think Dictionary Class is a great utility first because it does the same thing as an indexed array but with less code and in a way that others will understand better what you did. I certainly use it, but not abuse it.

If you have any questions please leave a comment. Cheers mates!

May 12

Introduction.

Breaking standard browser experiences with Flash is an old problem and i’ve seen that although there are a bunch of tutorials for As2 and some for As3, using different or same adapted Javascript library there is still a big question mark about this issue.In the past 2 days i’ve tried to find the best solution for this problem, I’ve surf the net and i’ve found some interesting things. I’ll try to show you the solutions which i think that are best from most of the aspects. The entire tutorial is written in As3.

Using the browser’s back button with Flash.

I’ve seen many people searching for a so called As3 solution, without javascript. Well, unfortunately , there is no such solution. Imagine the SWF as a guest and the HTML wrapper as a host, you simply can’t let your guest to give commands in your own house right? Of course you are polite and give him everything he needs but if he asks kindly. He could ask kindly via Javascript.

From all the Javascript libraries for Flash (As3), that help the SWF to ask or give kindly data to browsers, i think the best is SWFAddress. The next example shows how to enable the browser’s back button using SWFAddress.

Step 1: Download the latest distribution of SWFObject and SWFAdress. You can also download the FlashIDE example and follow from there the tutorial.

Step 2: In your project folder (which should be empty right now) copy the swfobject.js and swfaddress.js into 2 folders with the same name as the files (swfaddress, swfobject). Next create an index.html that will serve as a wrapper for the swf. Put the next tags into it.

[-]View Code HTML4STRICT
<div id="flashcontent">
            This content here will be replaced by the SWF.</div>
<script src="swfobject/swfobject.js" type="text/javascript"><!--mce:0--></script>
        <script src="swfaddress/swfaddress.js" type="text/javascript"><!--mce:1--></script>
		<script type="text/javascript"><!--mce:2--></script>
 
<!-- Google Analytics Plugin is set to ignore your user role -->

The code simply creates a div with “flashcontent” id and puts in it the backbutton.swf (for better understanding please check the swfobject examples). There are 2 things here that we have to pay attention to. First, the order in which we add the swfobject.js and swfaddress.js, it will always be first the object and second the address, this is very important. Second, we have to put the Javascript after we create the div because the Javascript uses the div and we don’t want it to use a null value. Don’t forget to add the main.css to the index.html by using the “link” tag
Then, add the two AS3 classes from the SWFAddress package(SWFAddress.as and SWFAddressEvent.as) to the root directory of your project.

Step3:Now we have it all set up, the index.html (wrapper), the swfaddress.js, the swfobject.js and the CSS linked to it, and the two SWFAdress class at their place. What we need to do next is to create the SWF, so compile the backbutton.as Actionscript code with Flash.(don’t forget to name the document class “backbutton”).

To understand the code you need a basic knowledge in using Flash Components. If you don’t have it, but you choose to write the code don’t forget that when you create a new component by code (ex: var cd=new ComboBox) you need to add the component also in the Library ( Drag and Drop from the Component Panel to Library)

[-]View Code ACTIONSCRIPT
package {
	import flash.display.MovieClip;
	import fl.controls.ComboBox;
	import fl.data.DataProvider;
	import flash.events.Event;
	import fl.controls.TextArea;
	import fl.containers.UILoader;
	import flash.net.URLRequest;
	import SWFAddress;
	import SWFAddressEvent;
 
	public class backbutton extends MovieClip {
		private var dp:DataProvider = new DataProvider();
		private var myCombo = new ComboBox();
		private var mytextArea = new TextArea();
		private var mySWFAddress=SWFAddress;
		private var image=new UILoader();
		private var urlreq=new URLRequest();
 
		public function backbutton() {
 
			dp.addItem( { label:"Spring" , pictureUrl:"images/1.jpg" , shortDes:"We love it!!!"} );
			dp.addItem( { label:"Summer" , pictureUrl:"images/2.jpg" , shortDes:"Lazy days"} );
			dp.addItem( { label:"Winter" , pictureUrl:"images/3.jpg" , shortDes:"Is really cold here in Cluj"} );
 
			myCombo.dataProvider=dp;
			myCombo.x=50;
			myCombo.y=50;
			addChild(myCombo);
			myCombo.addEventListener(Event.CHANGE, onComboBoxChange);
 
			mytextArea.width = 300;
			mytextArea.height = 80;
			mytextArea.x = 200;
			mytextArea.y = 50;
			addChild(mytextArea);
 
			image.x=200;
			image.y=140;
			image.scaleContent=false;
			addChild(image)
 
			mySWFAddress.addEventListener(SWFAddressEvent.CHANGE, onLinkChange);
 
		}
 
		private function onComboBoxChange(e:Event) {
			var newLink = e.target.selectedIndex;
			mySWFAddress.setValue(newLink);
		}
 
		private function onLinkChange(e:SWFAddressEvent) {
			var newLink = mySWFAddress.getValue();
			newLink = newLink.substr(1);
			mytextArea.text = dp.getItemAt(newLink).shortDes;
			urlreq.url=dp.getItemAt(newLink).pictureUrl;
			image.load(urlreq);
			mySWFAddress.setTitle(dp.getItemAt(newLink).label);
			myCombo.selectedIndex = newLink;
		}
	}
}

So this is it, pay attention to the comments in the backbutton.as file to understand how it works. Everything should work just fine. If not, leave a comment, and i will help.
Here is a working example.
Just choose a item in the ComboBox and then hit the browser’s back button

Well I hope you got the idea, in the second part of the tutorial I’ll talk a little about how to implement something like this in a large application (best practices, design patterns and all).