Creating Flash Components for Distribution

During this tutorial I will explain how to create a FLA-based User Interface (UI) component. Like the components that come with Flash, it will be visible on the stage, the preview then automatically updating as you change its parameters. This specific example is a circular progress bar.


Preview

Here’s how our component will look. Click the example to see it working with random values:

But we’re not focusing on the SWF result in this tutorial. To see the component itself and change its skin, download the zip file, extract it, and run RoundProgress.mxp to install it. (You may need to download the Adobe Extension Manager first.)


Step 1: Configure Flash for UIComponent

UIComponent is the base class of all Flash components. All User Interface components which are already in Flash (like the ColorPicker, the Checkbox and so on) extend the UIComponent (or extend some class that extends the UIComponent); the reason being that the UIComponent makes it easier for developers to allow their components to be “skinned”.

When used, the UIComponent class recreates the object, removes everything on the stage and adds the skins. This is important for personalization of the component; the user can just double-click the component and edit it visually, with Flash. You just create a component avatar on Frame 1 and the skins on Frame 2, and the UIComponent class does the rest.

You can do all this manually, but it is much better using UIComponent – you’ll see why.

I have explained what the UIComponent is and what it does, but you have to configure the classpath for the UIComponent as it is not configured by default. So, a few steps must be followed:

  1. Go to Edit > Preferences (or Ctrl+U)
  2. Click ActionScript in Category
  3. Click ActionScript 3.0 Settings
  4. Where you have "Source path", click the "+" button and add $(AppConfig)/Component Source/ActionScript 3.0/User Interface
  5. Click OK until you’ve closed all the Preferences windows.

Step 2: New Flash Actionscript 3.0 File

Let’s start by creating a new Flash AS3 file. Save it as RoundProgress.fla, wherever you want (example: C:\RoundProgress\)


Step 3: Prepare the Folders

We will assume the package org.display for our component, so in the same folder that you’ve saved RoundProgress.fla, create a folder with a subfolder, /org/display (example: c:\roundprogress\org\display\)

This is where we will save our component ActionScript file. This is just used to create the component or edit it; you won’t give the final user the .as file.


Step 4: Configure the Library Folders

When we create a component for Flash the library organization is very important (perhaps even more so than usual). When you drag the component to the stage of a project its library assets will be automatically added to the project’s library, so keep it organized.

Create a folder in the library called RoundProgress Assets.

Inside this folder create two other folders, Skins and _private.


Step 5: Create the RoundProgress Object

Click Insert > New Symbol. For the name: RoundProgress; type: Movie Clip; linkage: check the options "Export for ActionScript" and "Export in frame 1"; for the class: org.display.RoundProgress; base class: flash.display.MovieClip (though it will be changed when we create the .as file for this object).


Step 6: Component Definition

Let’s treat the RoundProgress object as Component. To do this, open the library, right-click on the RoundProgress object and click "Component Definition".

In the window that opens, in the class field insert: org.display.RoundProgress (we will create this class later); in the options panel, check all the options, and for Edit Frame type "2" (it’s actually irrelevant). The most important field here is "Display in Components panel": this option allows the component to be shown show in the components panel when you publish it (we will see this later).

So far we have in our library the “RoundProgress” object as a Component and the folder “RoundProgress Assets” with subfolders “Skins” and “_private.”


Step 7: Configure the Timeline

As we will use the UIComponent, we will need three layers and two frames on each layer. We need two frames because UIComponent uses the dimensions of the first frame to define the size of the component, and uses the second frame for Skin Editing.

In the library, double-click the RoundProgress component to open it as a movie clip.

In the timeline, add two new layers, rename the top layer to “Avatar”, the middle layer to “Skins” and the bottom layer to “Shim.”

Also create a new blank keyframe for each layer (select Frame 2 and press F7). It should now look like the image:


Step 8: Avatar

No, not the movie, the Avatar is an object which the UIComponent takes as the size of the object, then removes. Let’s create a square with a white background and black outline (hairline).

Select the square and convert it to a movie clip (Modify > Convert to Symbol), with type: Movie Clip, and name: RoundProgressAvatar. It’s important that the registration point is set to the top left; the name is completely irrelevant.

Go to the library again and drag the RoundProgressAvatar to the folder “_private” inside “RoundProgress Assets.”

Then, double-click on the RoundProgress component again to edit it, select Frame 1 and the Avatar layer, and drag an instance of RoundProgressAvatar on to the stage (so it will be at Frame 1, on the Avatar layer of the RoundProgress component). Set its position to x:0 and y:0.


Step 9: Create the Background

The background will be one of the skins we will create, it will be the background of our RoundProgress component.

Create a new movie clip (Insert > New Symbol):

For the name we will use “RoundProgressBarBackground”; check “Export for ActionScript” and “Export in frame 1″; for the class we will use “RoundProgressBarBackground” just like the name; and for the base class, since we won’t use animation we will use “flash.display.Sprite” (but if you use flash.display.MovieClip it will work too).


Step 10: Draw the Background

Assuming in the last step you left the RoundProgressBarBackground object open (if not, double-click on it in the library to open it again), let’s draw a ring. First, draw a circle with a diameter of 150px.

Align it to top and left (Window > Align); its position will be x:0 and y:0.

If you copy and paste-in-place (using Ctrl+Shift+V) you will create a copy of the circle, but don’t deselect it, just change its size to make it a little bit smaller than the other circle. Then change its color, all without deselecting the copy of the circle. After this you can deselect it, so you will get a circle inside another, then you can select the smaller circle (which will have another color) and delete it, so you will be left with a ring.

Change its color alpha to 20%.

Now you can exit the Edit mode of RoundProgressBarBackground object.

Open the library and drag the RoundProgressBarBackground we have created to the folder RoundProgress Assets/Skins.


Step 11: Create the Face

The face is a copy of the background, but with the color alpha set to 100%; it must have exactly the same width and same height of the Background…

Open the library, right-click RoundProgressBarBackground and click "Duplicate". This will create another object just like the RoundProgressBarBackground; for the name of this use RoundProgressBarFace, for the type: MovieClip, check the options "Export for ActionScript" and "Export on frame 1", for the class use "RoundProgressBarFace", and since we don’t have animations set the base class to “flash.display.Sprite.”

Enter edit mode (in the library double-click the object) and set its color alpha to 100%.

If it is not in there yet, drag the RoundProgressBarFace object to the folder RoundProgress Assets/Skins.

So far we have in our library the RoundProgress component, the RoundProgressAvatar in the _private folder and the RoundProgressBarBackdround and RoundProgressBarFace in the Skins folder.


Step 12: The RoundProgress.as File

OK, the design is ready, now we will start the dirty job, the code… First create a new Actionscript File

Save it as RoundProgress.as in the org/display folder which was created in the beginning of the tutorial, and let’s start coding it.


Step 13: Package and Imports

Let’s create the package and import the necessary classes.

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

}

As we want to use the package org.display we saved our RoundProgress.as inside the org/display folder, so the package is org.display.

We import the class fl.core.UIComponent, which we will extend. This will be the base of our component and the Sprite class will be the mask.


Step 14: Create the Class

Now we’ll create the Class, extending the UIComponent Class.

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{
    }

}

Step 15: Variables

Next up, we create the variables used in RoundProgress

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{

    	private const RAD:Number=Math.PI/180;
		private var _face:Sprite;
		private var _background:Sprite;
		private var _mask:Sprite;
		private var _ratio:Number=0;

    }

}

The _face and the _background will be the skin for the face and background; we will use Sprites for these. The _mask will be an empty Sprite, the const RAD is just a conversion factor from degrees to radians, and the _ratio is the current progress value, which ranges from 0 to 1.


Step 16: Overriding configUI()

The protected configUI() function is from the UIComponent class; it is called when the object is created – almost like the constructor function, but it removes everything from the stage, so you have to recreate everything.

Since we are overriding the function configUI(), we need to call it in our class. If not, our script will run but nothing will be removed from the stage, so our Avatar will be there when we use the component. We call the superclass’s configUI() method by using super.configUI():

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{

    	private const RAD:Number=Math.PI/180;
		private var _face:Sprite;
		private var _background:Sprite;
		private var _mask:Sprite;
		private var _ratio:Number=0;

       	override protected function configUI():void{
        	//Call the superclass configUI function
			super.configUI();

            //Create a definition for the background
			var bgDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarBackground");

            //Create a definition for the face
			var fcDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarFace");

            //Create the background object, cast it as Sprite and add it in our RoundProgress object
			_background=addChild(new bgDef) as Sprite;

            //Create the face object, cast it as Sprite and add it in our RoundProgress object
			_face=addChild(new fcDef) as Sprite;

            //Create the mask object, cast it as Sprite and add it in our RoundProgress object, also setting the _face.mask as this object
			_face.mask=_mask=addChild(new Sprite()) as Sprite;
		}
    }
}

Note that since the addChild() function returns a DisplayObject we can instantiate an object when we create it and cast it as whatever we want (in this case I cast it as Sprite). In one single line I created the object, cast it as Sprite and added in our object.


Step 17: The draw() Method

The method draw() is also from UIComponent; it’s called when an property is changed in our FLA file and updates the live preview of the component. This allows the user see how the component will change on the stage, rather than having to compile a SWF. We’re going to override it so that when we change a value the draw method will be called.

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{

    	private const RAD:Number=Math.PI/180;
		private var _face:Sprite;
		private var _background:Sprite;
		private var _mask:Sprite;
		private var _ratio:Number=0;

       	override protected function configUI():void{
			super.configUI();
			var bgDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarBackground");
			var fcDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarFace");
			_background=addChild(new bgDef) as Sprite;
			_face=addChild(new fcDef) as Sprite;
			_face.mask=_mask=addChild(new Sprite()) as Sprite;
		}

        override protected function draw():void{
        	//it is always important to set the background and the face objects with the same width of the component
            //It doesnt resize automatically
			_background.width=_face.width=width;
			_background.height=_face.height=height;

            //Calculate the angle based on the ratio
            //The .1 is because if the graphics doesnt draw a little bit more it will stay a line of fail
			var angle:Number=(360.1*_ratio)-90;

            //store a little bit more than the radius of the face
			var h:Number=_face.height*.6;

            //If we resize our component but the width and height stay different, gets the width too
			var w:Number=_face.width*.6;

            //this is for offset mask, as we want to draw from the center of the face, we need to get this offset
			var dx:Number=_face.width/2;
			var dy:Number=_face.height/2;

            //Start drawing from center and create a line until the top of the object
			_mask.graphics.clear();
			_mask.graphics.beginFill(0x00FF00);
			_mask.graphics.moveTo(dx,dy);
			_mask.graphics.lineTo(dx,dy-h);

            //Create a segment of circle, this will be the mask of the _face object
            //These lines are what makes the magic, starting at -90 degrees and running around by the amount of degrees specified
			for(var i:int=-90;i<angle;i++){

            	//Math.cos will return the cos of the angle, multiplyed by the w (width radius)
                //As Math.cos needs to use radian as parameter we convert the angle i to radians by multiplying it by our constant RAD
				var px:Number=Math.cos(i*RAD)*w;

                //Math.sin will return the sin of the angle, multiplyed by the h (height radius)
                //As Math.sin needs to use radian as parameter we convert the angle i to radians by multiplying it by our constant RAD
				var py:Number=Math.sin(i*RAD)*h;

                //Here is the offset, it is based on the radius of the face
				px+=dx;
				py+=dy;

                //then we create a line to the position px and py
				_mask.graphics.lineTo(px,py);
			}
            //After the code is executed, we need the graphics return to the center of the _face object
            //So we line it to the first position, which is the offset
			_mask.graphics.lineTo(dx,dy);
			_mask.graphics.endFill();

            //it is always important to use super.draw() to update widths and heights
			super.draw();
		}
    }
}

Don’t worry too much about this code. As I said before, it’s not the focus of the tutorial.


Step 18: Creating the Ratio Property

Well, here we create the ratio property. This is like a variable, but it’s a function: we use the [Inspectable] tag immediately before the function’s definition so this property can be changed using the "Component Inspector" when we use it in Flash.

Let’s get to grips with [Inspectable]. We have some parameters that we can use on it, like defaultValue, name and some others. If using defaultValue then Flash will use it as the default value in the component inspector (where we can change the parameters); the name parameter defines how it will appear in the component inspector, but is not necessary. If you want to set another name for this for example you can use [Inspectable(name="MyCustomName",defaultValue=0)]. You can also set the Type (Number, String), but as it is set in our ratio property this is not needed.

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{

    	private const RAD:Number=Math.PI/180;
		private var _face:Sprite;
		private var _background:Sprite;
		private var _mask:Sprite;
		private var _ratio:Number=0;

       	override protected function configUI():void{
			super.configUI();
			var bgDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarBackground");
			var fcDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarFace");
			_background=addChild(new bgDef) as Sprite;
			_face=addChild(new fcDef) as Sprite;
			_face.mask=_mask=addChild(new Sprite()) as Sprite;
		}

        override protected function draw():void{
			_background.width=_face.width=width;
			_background.height=_face.height=height;
			if(!_mask) return;
			var angle:Number=(360.1*_ratio)-90;
			var h:Number=_face.height*.6;
			var w:Number=_face.width*.6;
			var dx:Number=_face.width/2;
			var dy:Number=_face.height/2;
			_mask.graphics.clear();
			_mask.graphics.beginFill(0x00FF00);
			_mask.graphics.moveTo(dx,dy);
			_mask.graphics.lineTo(dx,dy-h);
			for(var i:int=-90;i<angle;i++){
				var px:Number=Math.cos(i*RAD)*w;
				var py:Number=Math.sin(i*RAD)*h;
				px+=dx;
				py+=dy;
				_mask.graphics.lineTo(px,py);
			}
			_mask.graphics.lineTo(dx,dy);
			_mask.graphics.endFill();
			super.draw();
		}

        [Inspectable(defaultValue=0)]		//allows the ratio property to be set in the Component Inspector
		public function get ratio():Number{
        	//Return the ratio value (0 to 1)
        	return _ratio;
        }
		public function set ratio(value:Number):void{
        	//If the value is out of the range it throws an error
			if(value>1 || value<0) throw new Error("Value is out of range (0-1)");

           	//set the variable _ratio
			_ratio=value;

            //Update the component for the new _ratio value
			draw();
		}
    }
}

Step 19: The setProgress() Function

Let’s add a function to set the progress, you can use a current value and a max value.

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{

    	private const RAD:Number=Math.PI/180;
		private var _face:Sprite;
		private var _background:Sprite;
		private var _mask:Sprite;
		private var _ratio:Number=0;

       	override protected function configUI():void{
			super.configUI();
			var bgDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarBackground");
			var fcDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarFace");
			_background=addChild(new bgDef) as Sprite;
			_face=addChild(new fcDef) as Sprite;
			_face.mask=_mask=addChild(new Sprite()) as Sprite;
		}

        override protected function draw():void{
			_background.width=_face.width=width;
			_background.height=_face.height=height;
			if(!_mask) return;
			var angle:Number=(360.1*_ratio)-90;
			var h:Number=_face.height*.6;
			var w:Number=_face.width*.6;
			var dx:Number=_face.width/2;
			var dy:Number=_face.height/2;
			_mask.graphics.clear();
			_mask.graphics.beginFill(0x00FF00);
			_mask.graphics.moveTo(dx,dy);
			_mask.graphics.lineTo(dx,dy-h);
			for(var i:int=-90;i<angle;i++){
				var px:Number=Math.cos(i*RAD)*w;
				var py:Number=Math.sin(i*RAD)*h;
				px+=dx;
				py+=dy;
				_mask.graphics.lineTo(px,py);
			}
			_mask.graphics.lineTo(dx,dy);
			_mask.graphics.endFill();
			super.draw();
		}

        [Inspectable(defaultValue=0)]
		public function get ratio():Number{
        	return _ratio;
        }
		public function set ratio(value:Number):void{
			if(value>1 || value<0) throw new Error("Value is out of range (0-1)");
			_ratio=value;
			draw();
		}

        public function setProgress($bytesLoaded:Number,$bytesTotal:Number):void{
        	//The ratio is just the current value divided by the maximum value
			ratio=$bytesLoaded/$bytesTotal;
		}
    }
}

Step 20: Percent Property

The percent property is like the ratio property, but instead of values between 0 and 1 you will use 0 to 100. It is a percentage calculation, it also returns a float value between 0 and 100:

package org.display{

	import fl.core.UIComponent;
	import flash.display.Sprite;

    public class RoundProgress extends UIComponent{

    	private const RAD:Number=Math.PI/180;
		private var _face:Sprite;
		private var _background:Sprite;
		private var _mask:Sprite;
		private var _ratio:Number=0;

       	override protected function configUI():void{
			super.configUI();
			var bgDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarBackground");
			var fcDef:Object=this.loaderInfo.applicationDomain.getDefinition("RoundProgressBarFace");
			_background=addChild(new bgDef) as Sprite;
			_face=addChild(new fcDef) as Sprite;
			_face.mask=_mask=addChild(new Sprite()) as Sprite;
		}

        override protected function draw():void{
			_background.width=_face.width=width;
			_background.height=_face.height=height;
			if(!_mask) return;
			var angle:Number=(360.1*_ratio)-90;
			var h:Number=_face.height*.6;
			var w:Number=_face.width*.6;
			var dx:Number=_face.width/2;
			var dy:Number=_face.height/2;
			_mask.graphics.clear();
			_mask.graphics.beginFill(0x00FF00);
			_mask.graphics.moveTo(dx,dy);
			_mask.graphics.lineTo(dx,dy-h);
			for(var i:int=-90;i<angle;i++){
				var px:Number=Math.cos(i*RAD)*w;
				var py:Number=Math.sin(i*RAD)*h;
				px+=dx;
				py+=dy;
				_mask.graphics.lineTo(px,py);
			}
			_mask.graphics.lineTo(dx,dy);
			_mask.graphics.endFill();
			super.draw();
		}

        [Inspectable(defaultValue=0)]
		public function get ratio():Number{
        	return _ratio;
        }
		public function set ratio(value:Number):void{
			if(value>1 || value<0) throw new Error("Value is out of range (0-1)");
			_ratio=value;
			draw();
		}

        public function setProgress($bytesLoaded:Number,$bytesTotal:Number):void{
			ratio=$bytesLoaded/$bytesTotal;
		}

        public function set percent(value:Number):void{
			if(value>100 || value<0) throw new Error("Value is out of range(0-100)");
            //Just some math...
			ratio=value/100;
		}
		public function get percent():Number{
			return ratio*100;
		}
    }
}

Save your document (remember, in /org/display/RoundProgress.as if you haven’t saved it yet).


Step 21: Live Preview

Nope, it isn’t finished yet. If we drag our component to the stage now, it will appear as the white square with the black outline, but if we test our movie it will show the component. This is because we haven’t created a “live preview” – the live preview can visualize a SWF of the component, and as we set the properties it will adjust and update visually too. If we don’t have a live preview only the avatar will be shown.

Let’s create our live preview; there are two ways I know of to create the live preview, so I’ll explain the one that works perfectly for me.

In the library of RoundProgress.fla, right-click over the RoundProgress component, click "Export SWC" and export in the same folder of the RoundProgress.fla file. The .swc file is a zipped file, so you can open it with WinRAR or something similar. Alternatively, you can rename the extension to “.zip” and open it that way.

Open the .swc as above and you will see some files. One of them is the library.swf; extract the library.swf to the same folder as the .fla file.


Step 22: Implementing the Live Preview

Go back to the Flash authoring environment. In the RoundProgress.fla file, open the library, right-click on the RoundProgress component and click the option "Component Definition".

In the Component Definition, note that in Parameters we have now the parameter ratio, which is the variable “ratio” and the value “0″ – this is the [Inspectable] we have defined with defaultValue=0 (the other parameters comes from the UIComponent class). It might not be configured yet; if not you need to open the Component Definition panel and click OK to update this, whenever you make changes in the .as file.

Now click the button "Set…" in the Live Preview section.

In this window that opens, select the option "Live preview with .swf embedded in .fla file", and click Browse:

…then select the library.swf which we extracted from the .swc file.

If you drag the RoundProgress component on to the stage you should now be able to see the “live preview”. Try changing the value of “ratio” in the Component Inspector.


Step 23: ComponentShim

So far, we have created the component and it is already working with a live preview, but if you want to distribute your component as an .mxp file, you will have to send the .as file in the .mxp file. Maybe you don’t want people having access to your source .as file, or, if you have a lot of .as files, maybe you would find it boring to create the .mxi file (explanation later). The best thing you can do is to embed the .as file inside the .fla file in a compiled clip, which we call the ComponentShim.

Note that if you drag any User Interface component to the stage there will be a ComponentShim object. For example, look in the library in Component Assets/_private – which is a compiled clip, but we won’t use this one, we will create our own.

Another good reason for using a shim compiled clip is that it is already compiled, so when you compile your .swf it will just be added, not recompiled, giving a faster compilation.

Let’s start by creating another .fla file and saving it with the name “RoundProgressShim.fla” in the same folder as “RoundProgress.fla.”

In the RoundProgressShim.fla document, open the library.

For each component which has external .as files you may create a new object in the RoundProgressShim.fla. As we have only one component with one .as file, we will create the shim for this component only.

Create a new Symbol in the library, it must be of type Movie Clip and for its name choose the same name as our component (in this case RoundProgress). Check the options "Export for ActionScript" and "Export in frame 1"; for the class we will use the name of the component, so use “org.display.RoundProgress.”

OK, this is our reference for the org.display.RoundProgress object (we need one reference for each component).

Now we create the shim source. Open the library again in RoundProgressShim.fla, and create a new Symbol named “RoundProgressShim source”. Check the options "Export for ActionScript" and "Export in frame 1"; for its class use org.display.RoundProgressShim (this is irrelevant); for its base class use flash.display.Sprite. Note that the name and the class don’t exist, really, but this will be our compiled clip, so to avoid conflicts it can’t have the same name or the same class as our component…

Now in the library, right-click on “RoundProgressShim source” and select "Convert to Compiled Clip"; now we will have one more object in the library called "RoundProgressShim source SWF". Rename it to "RoundProgressShim".

OK, our custom ComponentShim is created, just save the RoundProgressShim.fla in the same folder as the RoundProgress.fla, and close RoundProgressShim.fla.


Step 24: Using the RoundProgressShim

Back in our RoundProgress.fla document, click File > Import and click "Open external library" (Ctrl+Shift+O), find and select the RoundProgressShim.fla and open it as library.

Put the two libraries side by side, the library of RoundProgress.fla and the library of RoundProgressShim.fla.

Now drag the RoundProgressShim object from the RoundProgressShim.fla library to the RoundProgress Assets/_private folder in the RoundProgress.fla library.

…and now you can close the RoundProgressShim.fla library.

Go into edit mode of the RoundProgress component again (double click on RoundProgress object in the library), select the layer Shim, and go to Frame 2.

Now just drag the RoundProgressShim from RoundProgress Assets/_private in the library to the stage.

OK, now our component is ready to use. Save it and let’s learn how to package it into an .mxp file, ready to distribute.


Step 25: Create the .mxi XML File

Create a new XML file outside Flash, you can use Dreamweaver for this, or even notepad. I’ll use Dreamweaver.

Save it as “RoundProgress.mxi” in the same folder as RoundProgress.as. It is very important you define the type (.mxi), or else you’ll save just as a .xml file which is no good to us.

Copy the XML I’ve created for this tutorial and paste into your RoundProgress.mxi:

<macromedia-extension name="RoundProgress Bar" version="1.0" type="Library">
	<author name="Andre Cavallari" />
	<products>
		<product name="Flash" version="9" primary="true" />
	</products>
	<description>
		<![CDATA[A Circle Progress Bar]]>
	</description>
	<ui-access>
		<![CDATA[window - Components (ctrl+f7)]]>
	</ui-access>
	<files>
		<file name="RoundProgress.fla" destination="$flash/Components" />
	</files>
</macromedia-extension>

Let’s break down the XML file: the first line is where we assign the name of our component (this is for the Adobe Extension Manager only, not for Flash) the version and the type (which is Library; for other types check the Adobe Extension Manager manual).

The author tag is to define the author of the package. Again, this is only for the extension manager.

The product tag defines which product your component is for. In our case it’s for Flash CS3 or CS4, so for name we use “Flash”, version being “9″ (CS3).

The description tag is for a description in Adobe Extension Manager. It can’t be null, but you may write anything there. The CDATA tag tells us that we can have HTML code inside so it won’t try to read as xml.

Inside the ui-access tag you can define how to use your component, how to access it in the Flash authoring tool.

The files tag contains the list of the files that will be copied to Flash’s configuration folder. In our case we will copy just the RoundProgress.fla, as we created the RoundProgressShim, we won’t need to copy the org/display/RoundProgress.as too. If you have more files to copy you may specify them inside the files tag (hence why having lots of AS files could make this step boring!)


Step 26: Package the MXI into MXP

The .mxi file simply gives instructions on how the Adobe Extension Manager should create the .mxp file. The .mxp file is like a zipped file, but if you try to open it in any zip application or rename it, it will return an error. This is because its compression algorithm is different to the zip algorithm. However, the Adobe Extension Manager can read the contents of the mxp file and the instructions of the mxi file, and will use this information to install your component.

When you install the MXP file with Adobe Extension Manager, the MXI file is also copied for later removal of the component; it will be in the configuration folder of Flash inside the Extension folder.

If it’s all OK you can now find the .mxi file you just created and double-click on it to open with Adobe Extension Manager.

When the extension manager opens, it will ask where you want to save your extension package. Let’s select the same folder as the RoundProgress.fla, though it can be anywhere since the RoundProgress.fla is inside the MXP file now.

It will then generate and save your MXP file.


Step 27: Using the .mxp Extension

It is important that you do this with Flash if your Adobe Flash language isn’t the same as the computer language (this is a bug in CS4 extension manager: let’s say that your computer is in Portuguese language, but Flash was installed in English language; if you just double-click an .mxp file and add it, the extension manager will understand that the language that it must install in is in Portuguese, not English, so in the configuration folder of Flash, instead of using the /en folder it will create a new folder /pt and copy the files there instead. If you open Flash, click Help and select the option "Manage extensions" it will open the extension manager in the same language as Flash, so anything you add here will be in the correct place.)

Open the Extension Manager via Flash (Help > Manage extensions).

In the Extension Manager click "install" at the top of the application.

Find the .mxp file, and agree with anything you need to. OK, it is installed; you can now close the Extension Manager. You’ll also need to close and re-open Flash for these changes to take effect.


Step 28: Test Your Component

Create a new Actionscript 3.0 file and save it anywhere, for example in c:\test\RoundProgressTest.fla

Set its stage size to 170×170px then go to Window > Components.

Note that our component is in the list now, as it is in the RoundProgress.fla it will appear in the RoundProgress folder with the name of the component inside. If we wanted it in the User Interface folder we would need to save the .fla as “User Interface.fla”, but this isn’t good practice since a file can overwrite others.

Now drag the RoundProgress component on to the stage. You can see that the live preview will work now, it will show our component with the skins, etc.

Set the component’s position to x:10 and y:10, just to center the component in the stage. Open the component inspector ("Window -> Component Inspector"), and with our component selected on stage look at the parameters tab. There you can see the parameters of our component, so change the ratio value to 0.3 and you will see the live preview update.

You can double-click it to edit its skins and you can put a text label down next to each skin to identify them (the UIComponent will remove everything). Also, you can open the library and in RoundProgress Assets/Skins you can double click each skin to edit them – but remember: the circle’s size must not be changed when editing the skin, if you want it bigger or smaller resize the component on the stage.

Important: If you set the ratio value in an ActionScript file, let the parameter in the Component go to its default value (0 in our case).

The parameters we can set and get are ratio and percent: the ratio range is from 0 to 1, and the percent range is from 0 to 100. Both do the same thing but the ranges are different. Also, we have the method setProgress(), with 2 parameters: the first is the current value and the second is the maximun value.


Conclusion

Now you’ve learned how to create a Flash component, you can start creating your own components, selling then on ActiveDen, or creating some freebies for us here. I hope you like it and if you have any questions just ask in the comments.

One last thing: if you want to use a Tween in the example at the top, you can: let’s assume the instance name of our component is progressbar, and our tween engine is TweenLite; you can set the ratio to 0 in the component inspector then tween it to any value bigger than 0 and smaller than 1. For example:

	TweenLite.to(progressBar,.5,{ratio:.75});

Quick Tip: A Guide to Cross Domain Policy Files

Every Flash or Flex developer who has had to access remote resources has come across a crossdomain.xml policy file at some point. This article takes a look at what these policy files are, how they work and how you can create one for yourself.

Example

Let’s take a look at an example of what we’re talking about:

What’s so special about this? Well, the SWF is loading the smiley picture from http://mytestgae.appspot.com/images/smiley.jpg, not from the Activetuts+ domain. Without a cross domain policy file, trying to load the image would trigger a SecurityError.


What is a Cross Domain Policy File?

The security model known as the "same origin" policy, implemented by most modern web browsers, prevents some types of content from being accessed or modified if the file exists on another domain. It’s not a hard and fast rule; HTML pages will happily display images and HTML from pages on other domains. But for JavaScript the same origin policy prevents a document or script loaded from one origin from getting or setting properties of a document from another.

Flash includes a similar security policy which generally prevents a Flash application from accessing data that is hosted on a remote domain. However there are many circumstances where it is not only useful but expected that resources will be accessed remotely. An online photo album would find itself limited if external applications could not download its images. It would also be silly if a web service didn’t allow outside applications to interact with it.

For this reason it’s possible to create an XML file, called crossdomain.xml, that specifies how data on a domain can be accessed by a Flash application hosted on a remote domain. For the most part these policy files are quite simple, but there are a few details that it is useful to be aware of.

If you are hosting content that you want to be accessed by external Flash applications, you will need to create a crossdomain.xml file. Let’s start by taking a look at a basic example.


Step 1: A Basic crossdomain.xml File

Here is a very simple crossdomain.xml file. When this file is hosted on the root of your domain it permits external Flash applications access to all the resources on your domain.

<?xml version="1.0"?>
<cross-domain-policy>
<allow-access-from domain="*" />
</cross-domain-policy>

The policy file contains a single <cross-domain-policy> tag. Inside this you can have zero or more <allow-access-from> tags. Each <allow-access-from> tag can be used to define a domain or IP address from which a Flash application can access the local resources. The attribute domain="*" specifies that all domains have access. This is thanks to the asterisk wildcard, which is used here to match all domains and IP addresses.

For most situations this "allow all" policy file is sufficient. It grants Flash applications access to all pubic resources, while any security you have in place (like password protected pages) will still prevent Flash applications from accessing sensitive data.

(Note that you cannot put a crossdomain.xml file on your domain that will allow SWFs also on your domain to access remote files on another domain!)


Step 2: Specified Domains

If you do not want to allow global access to your public resources, the domain attribute in the <allow-access-from> tag can be used to grant access to specific domains.

You can specify a domain in its entirety. The example below will give access to Flash applications hosted in the www.example.com domain.

<allow-access-from domain="www.example.com" />

You can use the asterisk wildcard to match those domains that end with the given suffix. Here we grant access to Flash applications on the domains example.com, www.example.com, whatever.example.com etc.

<allow-access-from domain="*.example.com" />

Step 3: Specified IP Addresses

You can specify access by IP address just as you can grant access to Flash applications hosted on specified domains. The same tag and attributes are used, except in this case you use an IP address:

<allow-access-from domain="123.456.789.123" />

Step 4: Working with HTTPS

By default a Flash application hosted on an HTTPS server can only access resources on remote HTTPS servers. But given the overhead that HTTPS can add to a server you may not want to use it. In this case setting the secure attribute to false will allow a Flash application on an HTTPS server to access data from an HTTP server.

<allow-access-from domain="*" secure="false"/> 

Step 5: Remote Flash Applications

So what if you don’t want remote Flash applications accessing your data? You can either create a crossdomain.xml file that does not include any <allow-access-from> tags:

<?xml version="1.0"?>
<cross-domain-policy>
</cross-domain-policy>

Or you can simply not have a crossdomain.xml file at all.


Step 6: Granular Control of Subdirectories

A cross domain policy file will control access to the directory it resides in, and all the subdirectories beneath it. This is how placing a "allow all" policy file at your domain root allows access to your entire domain. But there may be situations where you want to only allow access to a certain subdirectory.

With the latest versions of the Flash Player this requires two XML files. First you need to place a crossdomain.xml file in the root of your domain that allows Flash to process additional cross domain policy files within the subdirectories. This is done with the <site-control> tag. In the example below we set the permitted-cross-domain-policies attribute to all, which means that the cross domain policy files that may exist in the subdirectories will be processed. This behavior is a change in Flash Player 9 Update 3 and up. Previously policy files in subdirectories were processed by default without having to set the permitted-cross-domain-policies attribute.

Note that we have not added any <allow-access-from> tags, which means in the absence of an additional crossdomain.xml files in the subdirectories, remote Flash applications will not have access to the resources on this server.

You can find out more about the meta policy options in this article.

<?xml version="1.0"?>
<cross-domain-policy>
<site-control permitted-cross-domain-policies="all"/>
</cross-domain-policy>

Next, you place a crossdomain.xml file in the subdirectory you wish to control.

To see an example of this in action check out this file. This policy file, in the root of the http://mytestgae.appspot.com/ domain, uses the <site-control> tag to delegate control to any crossdomain.xml files that may exist in the subdirectories. Then this policy file in the /images/ subdirectory grants full access to the directory and any subdirectory beneath it. So a remote Flash application could access the smiley face image in the images directory like so:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute"
	width="550"
	height="400"
	applicationComplete="onAppComplete()">
	<mx:Image id="image" scaleContent="true" horizontalCenter="0" verticalCenter="0"/>
	<mx:Script>
		<![CDATA[
			private function onAppComplete():void
			{
				Security.loadPolicyFile("http://mytestgae.appspot.com/images/crossdomain.xml");

				var loaderContext:LoaderContext = new LoaderContext();
				loaderContext.checkPolicyFile = true;

				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener(
					Event.COMPLETE,
					function(event:Event):void
					{
						image.source = event.currentTarget.content;
					}
				);
				loader.load(new URLRequest(encodeURI("http://mytestgae.appspot.com/images/smiley.jpg")), loaderContext);
			}
		]]>
	</mx:Script>
</mx:Application>

However, access to the smiley face image in the /images-restricted/ directory is not permitted because there is no crossdomain.xml file in the images-restricted directory to override the (lack of) access granted by the crossdomain.xml file in the root of the domain. Running the code below will result in an exception being thrown:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
	xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute"
	width="550"
	height="400"
	applicationComplete="onAppComplete()">
	<mx:Image id="image" scaleContent="true" horizontalCenter="0" verticalCenter="0"/>
	<mx:Script>
		<![CDATA[
			private function onAppComplete():void
			{
				var loaderContext:LoaderContext = new LoaderContext();
				loaderContext.checkPolicyFile = true;

				var loader:Loader = new Loader();
				loader.contentLoaderInfo.addEventListener(
					Event.COMPLETE,
					function(event:Event):void
					{
						image.source = event.currentTarget.content;
					}
				);
				loader.load(new URLRequest(encodeURI("http://mytestgae.appspot.com/images-restricted/smiley.jpg")), loaderContext);
			}
		]]>
	</mx:Script>
</mx:Application>

The exception reads:
SecurityError: Error #2123: Security sandbox violation: LoaderInfo.content: file:///D|/CrossDomain.swf cannot access http://mytestgae.appspot.com/images-restricted/smiley.jpg. No policy files granted access.
at flash.display::LoaderInfo/get content()
at MethodInfo-635()


Step 7: Cross Domain Policy vs. Firewall

So from the above information it looks like cross domain policy files can be used to effectively restrict access to Flash applications not hosted on your own domain. While that is true, you should not rely on a cross domain policy file to restrict access to sensitive information. While Flash may respect a crossdomain.xml policy file, other platforms like PHP won’t. Do a search for PHP Flash Proxy to see what I mean. By using a proxy it’s possible to get access to any publicly available data regardless of the existence of cross domain policy files. And you don’t even have to pay for a PHP server – as I will demonstrate in a future article, Google App Engine can be used as a proxy with no up front costs.

The bottom line is that cross domain policy files provide a way to selectively grant access to local resources by remote Flash applications, but only if everyone plays by the rules. If you want to ensure that your private data stays private, there is no substitute for a firewall.


Conclusion

Dealing with cross domain policy files doesn’t need to be complicated. Once you understand the basics of how they work it is quite easy to grant or restrict access to your data by remote Flash applications. Just be aware that they are not as secure as they might initially seem.

I hope you liked this Quick Tip, thanks for reading!

Create New Features for Flash with JSFL

In this introduction to the JavaScript for Flash (JSFL) scripting language, you’ll learn how to automate repetitive tasks and add new commands to the Flash authoring environment.


Introduction

We’ll start by exploring JSFL in general, seeing what it can do, then building up to a useful application of it: a command that can turn text into a button (with its hit area set correctly) in a single click.

Awesome font is Urbix by urbanpixel.ca

Step 1: Create a JSFL File

Open Flash and click File > New. Select Flash JavaScript File from the list, and save your new document as example.jsfl, anywhere you like.

JSFL is a plain text format, so you can open JSFL files in any text editor.


Step 2: Create a FLA

We’ll need a blank FLA to test our scripts, so create one of these, too. You don’t even have to save it; it’s just for testing.


Step 3: Write Some Script

In your JSFL file, paste the following code:

fl.getDocumentDOM().addNewOval({left:100, top:150, right:150, bottom:200});

Even if you’ve never used JavaScript before, the syntax is similar enough to ActionScript that you can guess what it does:

  • fl is an object representing the Flash application itself
  • getDocumentDOM() returns the currently open FLA
  • addNewOval() draws an oval to the FLA, with the parameters given

Step 4: Run the Script

If you’re editing the JSFL in Flash, run the script by clicking the big triangular Play button in the toolbar. Otherwise, double-click the JSFL file on your computer and it will automatically run in Flash.

You should see a circle appear, using whatever colors you had selected. Great! Now whenever you need to draw a 50px circle centered at (125, 125), you don’t even need to draw it.


Step 5: Make the Script More Codey

This is kind of a dull result, though. Let’s make things more complex:

for (i=0; i<8; i++)
{
    fl.getDocumentDOM().addNewOval({left:(i*50), top:(i*50), right:(i*50)+50, bottom:(i*50)+50});
}

Yep – JavaScript has for-loops too. This time, run the JSFL by switching to your FLA, clicking Commands > Run Command, then finding your script file on your hard drive.

Check out the result:

Already it’s clear that this can be very useful for taking care of repetitive, precise tasks. For example, it would be easy to modify that code to create a grid of circles… and from there it’s a small step to creating a grid of buttons. No more copying, pasting, and gently nudging symbols around the stage to line them up properly.


Step 6: Trace

It’s always good to have a trace() command available when you’re testing something new. In JSFL, we have the fl.trace() function, which takes a single string (unlike AS3’s trace(), which can take several at once) and prints it to the Output panel. Try it out:

for ( var i = 0; i < 8; i++ ) {
    fl.getDocumentDOM().addNewOval({left:(i*50), top:(i*50), right:(i*50)+50, bottom:(i*50)+50});
	fl.trace( "i is: " + i.toString() );
}

The result:

i is: 0
i is: 1
i is: 2
i is: 3
i is: 4
i is: 5
i is: 6
i is: 7

Step 7: Add the Command to the Menu

Having to keep the JSFL open or browse to it whenever you want to use it would be a real pain. Instead, you can add it to the Commands menu so it’s just a couple of clicks away. (And once it’s there, you could even assign it a keyboard shortcut.)

All you have to do is move your example.jsfl file to Flash’s \Command\ folder. The location of this folder depends on your OS, though:

  • Mac OS X: [hard drive]/Users/userName/Library/Application Support/Adobe/Flash CS3/language/Configuration/Commands
  • Windows XP: [boot drive]\Documents and Settings\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands
  • Windows Vista: [boot drive]\Users\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands
  • Windows Vista (alt): [boot drive]\Users\username\AppData\Local\Adobe\Flash CS3\language\Configuration\Commands
  • Windows 7: [boot drive]\Users\username\Local Settings\Application Data\Adobe\Flash CS3\language\Configuration\Commands
  • Windows 7 (alt): [boot drive]\Users\username\AppData\Local\Adobe\Flash CS3\language\Configuration\Commands

The username folder will match the name you use to log in with, language will change depending on what you picked when you installed Flash (for English speakers it’ll probably be en-us or just en), and if you’re using a newer version of Flash than CS3, that folder will change too.

Once saved in that folder, it will appear in the Commands menu, using the name of the JSFL file:

Just click to run it. You can now edit the JSFL file inside the Commands folder, to speed things up.


Step 8: Retrieve Information from the FLA

JSFL can do more than run lists of commands. It can also get information about the FLA and the items in it, and make decisions based on that info.

For example, we could write a script to trace how many items are currently selected:

fl.trace( fl.getDocumentDOM().selection.length )

The selection object is actually an array, with each element containing one of the selected objects. That’s why selection.length gives us the number of objects selected.

This simple script gives an insight into how Flash works: try drawing a few circles, selecting them all, and running the script. It’ll return “1″. Create a few text fields, select them all, and run the script, and it’ll return a number equal to the number of text fields.


Step 9: Find the Type of an Object

We can get information about the objects inside that selection, too:

for ( var i = 0; i < fl.getDocumentDOM().selection.length; i++ )
{
	fl.trace( fl.getDocumentDOM().selection[i].elementType );
}

I have two text fields and a bunch of circles selected, and this script outputs:

text
text
shape

For a full list of objects and functions, explore the Extending Flash book in the Adobe LiveDocs.


Step 10: Modify Objects on the Stage

Here's a simple script that squashes all the selected shapes on the stage - but nothing else:

for ( var i=0; i < fl.getDocumentDOM().selection.length; i++ )
{
	if ( fl.getDocumentDOM().selection[i].elementType == "shape" )
	{
		fl.getDocumentDOM().selection[i].scaleY = 2;
	}
}

Before:

...and after:


Step 11: "Buttonize" Overview

You've got the basics. Now it's time for the meat of this tutorial.

We're going to create a script that takes a text field and turns it into a button. I'll walk through the steps this script will replicate; start a new FLA and put a text field in the middle, then follow along:

  1. Click the text
  2. Convert it to a symbol
  3. Go into Edit Mode
  4. Create new keyframes: over, down, hit
  5. Draw a solid rectangle covering the text to define the hit area.

It's quite simple, when you see it listed like that. But how do we do all of that in JSFL? What's the script?

We could look everything up in the LiveDocs, but there is a much easier way...


Step 12: The History Panel

Click Window > Other Panels > History to bring up the History panel:

Those are all the steps we need. If only they were in JSFL...


Step 13: The History Panel List in JSFL

Oh, right, they are in JSFL. Click this little button:

...then click View > JavaScript in Panel:

Result:

It's not exactly what we need, but it gives us some indication of where to look in the LiveDocs.


Step 14: Copy the History

Click the top history item that you need and shift-click the bottom to select all the steps in between. You can ctrl-click (cmd-click on Mac) individual items to deselect them from this list (I've removed some unnecessary mouse clicks from mine). Then, click that little menu button again and select Copy Steps. You can now paste them in to a JSFL file:

fl.getDocumentDOM().convertToSymbol('button', '', 'top left');
var lib = fl.getDocumentDOM().library;
if (lib.getItemProperty('linkageImportForRS') == true) {
lib.setItemProperty('linkageImportForRS', false);
}
else {
lib.setItemProperty('linkageExportForAS', false);
lib.setItemProperty('linkageExportForRS', false);
}
lib.setItemProperty('scalingGrid',  false);

fl.getDocumentDOM().enterEditMode('inPlace');
fl.getDocumentDOM().getTimeline().convertToKeyframes();
fl.getDocumentDOM().getTimeline().convertToKeyframes();
fl.getDocumentDOM().getTimeline().convertToKeyframes();
fl.getDocumentDOM().addNewRectangle({left:125.0, top:133, right:344.9, bottom:207}, 0);

Save this as Buttonize.jsfl.

(Alternatively, you can click the Save button to create a JSFL file in the Commands directory, in which case the script will have comments to help explain each step.)


Step 15: Test Script

Let's test the script as it is right now so that we can get a good idea of what we need to improve. Start another blank FLA, create a text field (put it in a different position, with different text), click it, and run the JSFL.

Did it work? Mine was not a success:

We can see that we'll need to move the box so that its size and position matches that of the text field.


Step 16: Get Text Field Dimensions

Fortunately, we already know how to get information about a selected item. We can guess what the dimension properties of the selected object will be called; let's try tracing them and see if we're right:

fl.trace( fl.getDocumentDOM().selection[0].x );
fl.trace( fl.getDocumentDOM().selection[0].y );
fl.trace( fl.getDocumentDOM().selection[0].width );
fl.trace( fl.getDocumentDOM().selection[0].height );

Surprise, surprise, yes, that works fine. Now we can use that information to draw the rectangle:

fl.getDocumentDOM().addNewRectangle({left:fl.getDocumentDOM().selection[0].x, top:fl.getDocumentDOM().selection[0].y, right:fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width, bottom:fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height}, 0);

Try it out:

...Oh.


Step 17: Store Information before Selection Changes

What happened? Well, when the script entered Edit mode, the selection changed; we're inside the Button symbol, so we don't have it selected any more. Watch out for that sort of error when working with JSFL.

This is easy to fix, though - we just have to store the left, top, right, and bottom properties early, before the selection changes:

var textLeft = fl.getDocumentDOM().selection[0].x;
var textTop = fl.getDocumentDOM().selection[0].y;
var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width;
var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height;

fl.getDocumentDOM().convertToSymbol('button', '', 'top left');
var lib = fl.getDocumentDOM().library;
if (lib.getItemProperty('linkageImportForRS') == true) {
lib.setItemProperty('linkageImportForRS', false);
}
else {
lib.setItemProperty('linkageExportForAS', false);
lib.setItemProperty('linkageExportForRS', false);
}
lib.setItemProperty('scalingGrid',  false);

fl.getDocumentDOM().enterEditMode('inPlace');
fl.getDocumentDOM().getTimeline().convertToKeyframes();
fl.getDocumentDOM().getTimeline().convertToKeyframes();
fl.getDocumentDOM().getTimeline().convertToKeyframes();
fl.getDocumentDOM().addNewRectangle({left:textLeft, top:textTop, right:textRight, bottom:textBottom}, 0);

Did it work? It did for me!


Step 18: Check for Potential Errors

What happens if we run the command without selecting the text? We get the same error as before:

We should check to see whether any objects are selected before doing anything:

if ( fl.getDocumentDOM().selection.length > 0 )
{
	var textLeft = fl.getDocumentDOM().selection[0].x;
	var textTop = fl.getDocumentDOM().selection[0].y;
	var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width;
	var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height;

	fl.getDocumentDOM().convertToSymbol('button', '', 'top left');
	var lib = fl.getDocumentDOM().library;
	if (lib.getItemProperty('linkageImportForRS') == true) {
	lib.setItemProperty('linkageImportForRS', false);
	}
	else {
	lib.setItemProperty('linkageExportForAS', false);
	lib.setItemProperty('linkageExportForRS', false);
	}
	lib.setItemProperty('scalingGrid',  false);

	fl.getDocumentDOM().enterEditMode('inPlace');
	fl.getDocumentDOM().getTimeline().convertToKeyframes();
	fl.getDocumentDOM().getTimeline().convertToKeyframes();
	fl.getDocumentDOM().getTimeline().convertToKeyframes();
	fl.getDocumentDOM().addNewRectangle({left:textLeft, top:textTop, right:textRight, bottom:textBottom}, 0);
}

Actually, we can do better than that... how about checking whether exactly one text field has been selected?

if ( fl.getDocumentDOM().selection.length == 1 )
{
	if ( fl.getDocumentDOM().selection[0].elementType == "text" )
	{
		var textLeft = fl.getDocumentDOM().selection[0].x;
		var textTop = fl.getDocumentDOM().selection[0].y;
		var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width;
		var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height;

		fl.getDocumentDOM().convertToSymbol('button', '', 'top left');
		var lib = fl.getDocumentDOM().library;
		if (lib.getItemProperty('linkageImportForRS') == true) {
		lib.setItemProperty('linkageImportForRS', false);
		}
		else {
		lib.setItemProperty('linkageExportForAS', false);
		lib.setItemProperty('linkageExportForRS', false);
		}
		lib.setItemProperty('scalingGrid',  false);

		fl.getDocumentDOM().enterEditMode('inPlace');
		fl.getDocumentDOM().getTimeline().convertToKeyframes();
		fl.getDocumentDOM().getTimeline().convertToKeyframes();
		fl.getDocumentDOM().getTimeline().convertToKeyframes();
		fl.getDocumentDOM().addNewRectangle({left:textLeft, top:textTop, right:textRight, bottom:textBottom}, 0);
	}
}

This opens up all sorts of other options. If several items are selected, you could loop through them all, and turn them all into buttons. If an object is selected that isn't a text field, you could treat it differently - perhaps it wouldn't need a rectangle for its Hit shape.


Step 19: Name the Button After the Text

A nice touch would be to give the Button symbol the same name as the text it contains. That would keep the Library tidy, too. But there's nothing in our script to suggest how we might do that.

We do know that the JSFL to convert a selection into a symbol is fl.getDocumentDOM().convertToSymbol(), thanks to the History panel. If you look that up in the LiveDocs, you'll find that the second parameter (which the History panel's script left blank) is called name, and described like so:

A string that specifies the name for the new symbol, which must be unique. You can submit an empty string to have this method create a unique symbol name for you.

Bingo! Of course, we don't know what the text says...


Step 20: Get the Text

We could have a guess:

fl.trace( fl.getDocumentDOM().selection[0].text );

Sadly, this returns undefined. Ah well.

Not to worry - a quick scan through the LiveDocs reveals this page on the Text object. In there we can find the function we're looking for: text.getTextString().

Add that to your script:

var textLeft = fl.getDocumentDOM().selection[0].x;
var textTop = fl.getDocumentDOM().selection[0].y;
var textRight = fl.getDocumentDOM().selection[0].x + fl.getDocumentDOM().selection[0].width;
var textBottom = fl.getDocumentDOM().selection[0].y + fl.getDocumentDOM().selection[0].height;
var textText = fl.getDocumentDOM().selection[0].getTextString();

fl.getDocumentDOM().convertToSymbol('button', textText, 'top left');

Test it.

Fantastic.


Wrap Up

Buttonize is a handy little command to have available if you need to mock up a UI quickly, but it wasn't the point of the tutorial. The goal was to get to grips with JSFL, and see where it could be used. I hope that the next time you're faced with an hour's work of tedious Flash chores, you'll figure out how to automate it with a script in half the time :)

Quick Tip: Compile a Debug Version of Your Flash Project

In this Quick Tip I’ll show you how to use Config Constants to compile different debug and release versions of your code, so you can easily switch between them.


Step 1: Config Constants Settings

A lot of people don’t know about Flash’s Config Constants because they’re new to CS4 and because they’re buried deep within two sets of tabs and two different windows. Here’s how to find them:

In your Flash file, open the Publish Settings (File > Publish Settings…) and click the Flash tab. Click the Settings button next to the Script: Actionscript 3.0 pulldown.

In this new window click the Config constants tab at the far right.

Where are the Config Constants?

Whew…


Step 2: Add the DEBUG Constant

You should see one constant (FLASH_AUTHORING) already in the list. Now we’ll add one of our own.

Click the plus button to add a new constant and give it the name ‘CONFIG::DEBUG’. In the Value field enter ‘true’.

Adding the DEBUG Constant

The interface here is pretty poor. If you’re having trouble getting the Value field to gain text focus try double clicking somewhere in that giant empty space to the right of the constant you just created. A little higher… more to the right… there! Remember CS5 is out soon – maybe they’ll have fixed this.


Step 3: Use the Constant in Your Code

Now that we have the DEBUG constant set up in our Flash file we can use it anywhere in our code:

CONFIG::DEBUG {
	trace("This code will only be compiled if DEBUG is true.");
}

The code that you place in between the braces will only be compiled into your SWF if the DEBUG constant is set to true.


Step 4: The Debug Publishing Profile

You can go into the Publish Settings and change the value of the DEBUG constant each time you want to switch between compiling a release and a debug version, but that quickly becomes tedious. To save some time you can set up a couple of different publishing profiles.

Go back to the Publish Settings and Click the ‘Rename Profile’ button. For some reason the icon for this is an ‘i’.

Name your profile ‘Debug’.

Rename Debug Profile

While you’re in here you might want to set some of the other options that will be handy for a debug build, like Permit debugging. I also find it helpful to change the audio compression settings for faster publishing of debug builds.

Permit Debugging

Step 5: The Release Publishing Profile

Once you have your Debug profile set up, hit the ‘Duplicate Profile’ button and name the new profile ‘Release’.

Release Profile

Define the settings for your release version. (Turning off Permit debugging, etc.)


Step 6: Change the DEBUG Constant

Go back to the Config constants in your Release profile and change the DEBUG constant’s value to ‘false’.

Change the DEBUG value

Conclusion

That’s it! You now have an easy way to switch between debug and release versions of your code.

This can be really handy in situations where you need different code in your program while you’re testing it than you’ll have in the final version. For example, if you’re game gets some of its data from a server or from another SWF that you don’t have access to while testing, you can feed in fake data to the Debug version.

You could also use it to set your game to start on the level you’re trying to test, without having to play through the entire the game.

When you’re done testing, just switch back to the Release profile and republish.

Build a Brilliant Binary Clock with Flash

In this tutorial we are going to create an unusual, but very cool kind of clock: a binary clock.


Final Result Preview

Let’s take a look at the final result we will be working towards:


Step 1: What Does Binary Mean?

Everyone knows how to count, but not everyone knows there are so many different ways to do so. We are used to a special way of counting named the decimal system, but we could also use the hexadecimal, octal or binary system, among others.

In our decimal system, we assign 10 to represent the total number of fingers and thumbs that we each have, and count up and down from there. But in binary, 10 represents just the total number of thumbs — so 10 in binary is equal to 2 in decimal; 11 in binary is 3 in decimal; 100 in binary is 4 in decimal, and so on. So rather than each column representing units, tens, hundreds, thousands, … (counting from right to left), they represent units, twos, fours, eights, …, doubling each time.

So the number 10 we normally see, can be represented in diferent ways:

The binary system is based on the number two, that’s why it is called binary, as opposed to the decimal system which we normally use and which has a base of 10. The binary system is the one used by computers to work, because we can use it to represent any number using a series of switches “on” (1) and “off” (0).

With this knowledge, can you figure out how to read the clock in the SWF?

If you want to learn more about this you can Google binary numeral system and check the info about it =)


Step 2: Create the Flash File

Create a new AS3 Flash file and name it “Binary_Clock.fla”.


Step 3: Set up the Stage

Go to the properties and change the size to 550×400 and the background color to #222222.


Step 4: Get TweenMax

Go to the TweenMax project webpage and download the library for AS3.


Step 5: Extract TweenMax

Unrar the file and copy the folder named “com” to the folder where you have your Binary_Clock.fla file.


Step 6: Create a Bit

Now, go to Insert > New Symbol and name it “Bit” with type Movie Clip.

This “Bit”” will represent a single digit of a number. It will have two states, in two different colors: one will represent 0 and the other will represent 1.


Step 7: Draw a Bit

Next, in the symbol you just created, make a new square of 50×50px.


Step 8: Modify the Bit

Change the color of the square to #00CBFF and center it.


Step 9: Create the Columns

Back on the stage, take some bits from the library panel and arrange them to create the columns we will use. You should end with something like this:


Step 10: Add Some Elements

If you want, you can add text labels and lines to make it more understandable:


Step 11: Assign Instance Names

For each bit, change the instance name on its properties panel. Give them the names such as the image below demonstrates:


Step 12: Link the FLA to a Document Class

Go to the properties panel and set the class field to “Main”, this is the name of the class we are going to create in the next step.

(Not sure what we’re doing here? Read this quick introduction to document classes.)


Step 13: Create the Document Class

With the stage completed, we can now start coding. First create a new ActionScript 3.0 file and save it as “Main.as”.

Add this code to the file:

package{
	import flash.display.MovieClip;

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

		}
	}
}

Step 14: Add the Imports Needed

We’ll begin by importing the necessary classes. Add this below the package declaration:

import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.TimerEvent;
import com.greensock.*;
import com.greensock.easing.*;

Step 15: Declare Variables

Next, we’ll declare some public variables. Add this below the class declaration:

public var clock:Timer=new Timer(1000);
public var date:Date=new Date();
public var hr:int;
public var min:int;
public var sec:int;
public var bits:Array;

Creating a new Date object automatically sets it to the current time.


Step 16: Assign Values

OK so now let’s add the code that will start the clock. This goes inside the Main() function:

//With this we assign the actual values for the clock to each variable
sec=date.getSeconds();
min=date.getMinutes();
hr=date.getHours();
clock.start();
clock.addEventListener(TimerEvent.TIMER, setTime);

Step 17: Create the setTime() Function

This is the function that will be called every second.

private function setTime(e:TimerEvent):void
{
	date=new Date();
	sec=date.getSeconds();
	min=date.getMinutes();
	hr=date.getHours();
}

Step 18: Convert Decimal to Binary

This function will change a decimal number to a binary array, which will be used later.

private function dec2bin(dec:int, length:int):Array
{
	var bin:Array = new Array();
	while((dec/2)>0)	//note this has the same effect as "while((dec/2)>=1)"
	{
		bin.push(dec%2);	//dec%2 is the *remainder* when dec is divided by two. 3%2=1; 4%2=0; 5%2=1; 6%2=0; etc.
							//in other words, dec%2 is 1 if dec is odd and 0 if dec is even.
		dec=dec/2;			//because dec is an int, it will be rounded
	}
	while(bin.length<length) bin.push(0);	//this is just padding the array with extra zeroes
	return bin;
}

So, dec2bin(13, 4) gives [1,1,0,1].


Step 19: Create the converter() Function

This function takes a decimal number and uses dec2bin() to convert it to the 2-column array we have in the display.

private function converter(num:int):Array
{
	var st:String=String(num);
	if (st.length==1) st='0'+st;
	var fDigit:int=int(st.charAt(1));
	var sDigit:int=int(st.charAt(0));
	var fColumn:Array=dec2bin(fDigit,4);
	var sColumn:Array=dec2bin(sDigit,3);
	var result:Array=fColumn.concat(sColumn);
	return result;
}

Step 20: Turning Bits On and Off

Now we need to add something that will turn the bits on and off; that’s what this function does:

//newBits is the 2-column array we get from converter(), target is "H" "M" or "S" to indicate which column to use
private function turnBits(newBits:Array, target:String):void
{
	//Loops through the 2-column array to change the state of the bit
	for(var a:int=0; a<newBits.length; a++)
	{
	   //This checks if you are now trying to access element 6 of the hour columns; remember that the H col only has 5 bits
		if((a!=6)||(target!="H"))
		{
			//if it is 0, get the instance named for example "S0" which will be the first bit then "S1" and so on
			if(newBits[a]==0) this.getChildByName(target+String(a)).alpha=.2;
			//it it is 1, change the alpha to 1 (Turn it on)
			else this.getChildByName(target+String(a)).alpha=1;
		}
	}
}

Step 21: Modify the Functions

A couple of modifications to the Main() and the setTime() Functions: we just need to call the function so the changes are made each second and at the start:

public function Main()
{
	sec=date.getSeconds();
	min=date.getMinutes();
	hr=date.getHours();
	turnBits(converter(sec),'S');
	turnBits(converter(min),'M');
	turnBits(converter(hr),'H');
	clock.start();
	clock.addEventListener(TimerEvent.TIMER, setTime);
}

private function setTime(e:TimerEvent):void
{
	date=new Date();
	sec=date.getSeconds();
	min=date.getMinutes();
	hr=date.getHours();
	turnBits(converter(sec),'S');
	turnBits(converter(min),'M');
	turnBits(converter(hr),'H');
}

Try it out, and you’ll see it correctly display the time. But we can do better…

Step 22: A Little Bit of Style

This is where TweenMax comes in. We will add glow and ease to give a better look to the clock. Modify your turnBits() function like so:

private function turnBits(newBits:Array, target:String):void
{
	for(var a:int=0;a<newBits.length;a++)
	{
		if((a!=6)||(target!="H"))
		{
			if(newBits[a]==0) TweenMax.to(this.getChildByName(target+String(a)), 1, {glowFilter:{color:0x00cbff, alpha:0, blurX:15, blurY:15,strength:1},alpha:.1});
			else TweenMax.to(this.getChildByName(target+String(a)), 1, {glowFilter:{color:0x00cbff, alpha:1, blurX:20, blurY:20,strength:.8},alpha:1});
		}
	}
}

And that’s it! We’ve finished our tutorial =)

Conclusion

Now we have an attractive clock which we could use as our screensaver or add to a webpage.

This is my first tutorial so I hope you liked it. Thanks for reading!

A Better Way to Build Flash Banners

Banner development is often plagued by multiple files, fragmented code and messy timelines. This tutorial will show you how you can create a project template to serve as a solid base which will help you develop robust banners quickly, freeing you up to focus on bringing the creative idea to life.


Step 1: Setting Up Project Folder Structure

When building multiple banners, good file management is essential to keep your workflow efficient. Start your banner project template by creating the folder structure shown below:

Step 1

Step 2: Creating A Photoshop Template

Now we are going to create a set of Photoshop templates to use when starting to design a banner campaign. (If you don’t have Photoshop don’t worry, you can skip ahead to Step 5). The Interactive Advertising Bureau maintain Ad Unit Guidelines that list the common dimensions of ad units (banners). For the purposes of this tutorial, we’re going to create the three most common:

  • The Wide Skyscraper (160px wide x 600px tall)
  • The Medium Rectangle (300px wide x 250px tall)
  • The Leaderboard (728px x 90px tall)

Let’s start by creating the template for The Wide Skyscraper. Open Photoshop and select File > New. Configure the properties for your new Photoshop document as shown below:

Step 2

Step 3: Adding Layer Groups

To keep the layers in your Photoshop file as structured as your project folders when it’s time to produce a banner design, we’re going to add Layer Groups in the template file to hold core design elements.

Using New Group from the menu in the top-right corner of the Layers panel create the Layer Group structure shown below:

Step 3

The ‘Background’ layer group will hold design elements that are in the background of your banner at all times, for example a color or a texture.

The ‘Foreground’ layer group will hold design elements that are in the foreground of your banner at all times, such as a company logo.

The ‘Frame’ layer groups will hold design elements of the key moments in your banner sequence or interaction. This could include key messages, critical points of an animation, or user interfaces.


Step 4: Save

Now your template is ready to save. Go to File > Save As and navigate to the ‘design’ folder in your project folder structure. Name the file according to its dimensions, in this case ‘160×600′ and ensure it’s in Photoshop format, with Layers checked.

Step 4

That’s your first banner template created! Repeat these steps for The Medium Rectangle (300px wide x 250px tall) and The Leaderboard (728px x 90px tall). With these Photoshop templates completed, we’re ready to move into Flash.


Step 5: Creating Your Flash Project

Let’s start by creating a Flash Project so you can navigate your file structure in the Flash IDE. Open Flash CS4 (the process is very similar in Flash CS3 although the Flash interface will differ) and go to Window > Other Panels > Project. In the Project panel, click on the Projects dropdown and select New Project. Specify the Project name as ‘BannerTemplate’.

For the Root Folder, navigate to the /banner_template/development/ folder you created in Step 1 using the folder icon. Make sure the ActionScript version is set to ActionScript 3.0 and click Create Project.


Step 6: Flash Project Classes Folder

Now we are going to set the Flash Project properties to help Flash do the work of stubbing out our classes for us. Click the dropdown with the gear icon in the top right corner of the Project panel and select Project Properties. For the ‘Save classes in’ field, navigate to the /as/ folder you created in Step 1 and click OK.


Step 7: Banner Package Folder

If you performed the last step correctly, you should see little code brackets are now on your /as/ folder icon. We are now going to create a folder for all classes specific to our banner templates. Select the /as/ folder and click the new folder icon in the bottom of the panel. In the dialog box that appears name your folder ‘banner’ and click OK.


Step 8: Banner Base Document Class

Now (at last!) you are ready to create your banner base document class. If you’re not familiar with using document classes (or classes in general), it’s a good idea to read this quick tip first.

With the /as/banner/ folder selected, click the Create Class icon in the bottom of the panel. In the Class field add the class name ‘Banner’ after the package name ‘banner.’ and click Create Class.

Now we need to take this class stub and modify it to a functional base document class. Add to the ActionScript to reflect the code shown below:

package banner {

	import flash.display.MovieClip;

	public class Banner extends MovieClip {

		// Constants:

		// Public Properties:

		// Private Properties:
		private var config:Object;

		// Initialization:
		public function Banner(config:Object = null):void {
		}

		// Public Methods:
		public function init():void {
			trace("Banner class initialized");
		}

		// Protected Methods:
	}

}

Let’s quickly cover the changes we’ve made to the Banner class:

  • Imported the MovieClip class.
  • Made the class Banner extend MovieClip (so it can be used as a document class).
  • Made the Banner document initialization function receive an optional config Object that we can use to pass in parameters.
  • Created a public init() function that outputs a trace when called. The reason why this is handy will be explained when we start to create the banner .FLAs.

Right now this isn’t doing much, but the important thing here is to build a class structure that allows us to centralize banner logic, reducing code repetition. From here, we can now extend the Banner class to create our individual banner document classes.


Step 9: Banner Document Classes

Let’s start with the class file for The Wide Skyscraper. Create a “WideSkyscraper” class in your Flash project /as/banner/ folder just as you did for the “Banner” class. Take the generated class stub code and add to it so it looks like this:

package banner {

	public class WideSkyscraper extends Banner {

		// Constants:
		// Public Properties:
		// Private Properties:
		private var config:Object;

		// Initialization:
		public function WideSkyscraper() {
			super();
		}

		// Public Methods:
		public override function init():void {
			trace("WideSkyscraper class initialized");
			super.init();
		}

		// Protected Methods:
	}

}

Let’s go over the changes we’ve made to the WideSkyscraper class:

  • Made the WideSkyscraper class extend Banner.
  • Called the base Banner class document function with super() in the WideSkyscraper document function.
  • Overridden the base Banner class init() function with a custom init() function that outputs a trace when called, then calls the Banner class init() function.

Now repeat this step to create the banner document classes for the MediumRectangle and the Leaderboard. With this done, our document class structure is now in place.


Step 10: Creating Your Banner .FLAs

Now we can start to create the .FLA files we need. Again, let’s start by creating the template for The Wide Skyscraper (160×600).

Open Flash CS4 and select File > New. Select “Flash File (ActionScript 3.0)” as the Type and click OK. In the Properties panel, edit the Publish and Properties settings as shown below:

Now save your file as “160×600.fla” in the /development/ folder of your project.


Step 11: Setting A Relative Source Path

We’re now going to set a relative source path and a relative publish path. This becomes important when you want to make a copy of your banner template project, rename it and start working, or when you want to give the template to someone else. Absolute paths can be a real pain to update (especially across multiple files!) every time you want to start a project.

To set the source path go to File > Publish Settings and click the Flash tab. Now click the Settings button beside the Script dropdown to open the Advanced ActionScript 3.0 Settings window. Make sure Source Path is the active tab and click the ‘+’ to add the ‘./as’ path. Now you can add the text ‘banner.WideSkyscraper’ in the Document Class field. Your window should look like this:

Click OK and your document is now linked to the WideSkyscraper class you created in Step 9.


Step 12: Setting A Relative Publish Path

To set the publish path, go to File > Publish Settings and click the Formats tab. We don’t need the HTML file, so uncheck this box. In the publish path for the SWF, target the /www/ folder in your project folder as shown below. If everything looks correct, click OK. Your compiled swf will now be put in the /www/ folder when you preview or publish it.

There’s a little more info on this in this Quick Tip screencast.


Step 13: The Main Timeline

For some reason, some ad serving systems require the first frame of your movie to be blank (Eyeblaster is an example of this), or to import their classes/include their ActionScript on the first frame. Often the Flash extensions you can install for these ad serving systems will refuse to package your file if you don’t comply with this stipulation.

This is where the init() function you created in your document class earlier comes in. To ensure our template can be used in this situation, we are going to create a two frame timeline with the first frame blank, the second one containing a stop action and a call to the init() function as shown below:

If you compile this file now you should get the following in your Output panel which confirms your WideSkyscraper document class and Banner base document class are working:

WideSkyscraper class initialized
Banner class initialized

Step 14: Creating A Library Symbol Class

Now we’re going to create a library symbol to hold the banner creative, whether it’s an animation or an interface. Go to Insert > New Symbol and give it the name “creative”, check Export for ActionScript and give it the class “Creative”. Make sure the type is Movie Clip and click OK.

Now add some placeholder text on the stage as shown below so you can see something when you add it to your stage in code later:

And that’s all we need from the .FLA file! Go ahead and create the other .FLAs for The Medium Rectangle (300 wide x 250 tall) and The Leaderboard (728 wide x 90 tall). With this in place, we can revisit our Banner document class and start adding core functionality across all these banners.


Step 15: Adding A Background Sprite

Nearly all banner guidelines advise you to place a solid background color in your Flash file as the Stage background color can be overwritten when the Flash object is embedded in an HTML page. Rather than going into every .FLA and drawing a shape on the stage, we can centralize this task in code. Open up your Banner class and update the file to reflect the code shown below:

package banner {

	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Graphics;

	public class Banner extends MovieClip {

		// Constants:
		private const BG_COLOR:Number = 0x0E0E0E;

		// Public Properties:

		// Private Properties:
		private var config:Object;

		// Initialization:
		public function Banner(config:Object = null):void {
		}

		// Public Methods:
		public function init():void {
			trace("Banner class initialized");

			// Create background
			var bg:Sprite = new Sprite();
			bg.graphics.beginFill(BG_COLOR);
			bg.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
			bg.graphics.endFill();
			addChild(bg);
		}

		// Protected Methods:
	}

}

Let’s recap the modifications we’ve made to the Banner class:

  • Imported the Sprite and Graphics classes.
  • Added a constant BG_COLOR and assigned to it a hexadecimal value.
  • Created a bg sprite and drawn a rectangle with a fill of BG_COLOR that covers our whole stage.
  • Added bg to the display list.

Now all you need to do is change the BG_COLOR value to get the right color background in all your banners.


Step 16: Adding to the Display List

Now we need to add the Creative symbol that we created in Step 14 to the display list as this will be the container for the creative execution. This is really easy to do, just update the init() function to this:

// Public Methods:
public function init():void {
	trace("Banner class initialized");

	// Create background
	var bg:Sprite = new Sprite();
	bg.graphics.beginFill(BG_COLOR);
	bg.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
	bg.graphics.endFill();
	addChild(bg);

	// Add Creative
	var creative:Creative = new Creative();
	addChild(creative);
}

Step 17: Adding A Clickable Area

Another common requirement is for the banner’s clickable area to open a new window based on a “clicktag” variable passed in from the HTML page when the Flash object is embedded. Let’s create a utility class to handle this for us. In the Flash Project panel navigate to your /as/banner/ folder and create a new subfolder called /util/. Create a new class in here called ‘ClickArea’ and code this as shown below:

package banner.util {

	import flash.display.Sprite;
	import flash.display.Graphics;
	import flash.display.Stage;
	import flash.events.MouseEvent;
	import flash.net.URLRequest;
	import flash.net.navigateToURL;

	public class ClickArea extends Sprite {

		// Private Properties:
		private var clickthroughURL:String;

		// Initialization:
		public function ClickArea(loaderInfo:Object,stage:Stage) {

			// Create clickable area
			this.graphics.beginFill(0x00FF00,0);
			this.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
			this.graphics.endFill();

			// Determine clickthrough URL (by checking known naming conventions)
			if(loaderInfo.parameters.clicktag != null) {
				clickthroughURL = loaderInfo.parameters.clicktag;
			} else if(loaderInfo.parameters.clickTag != null) {
				clickthroughURL = loaderInfo.parameters.clickTag;
			} else if(loaderInfo.parameters.clickTAG != null) {
				clickthroughURL = loaderInfo.parameters.clickTAG;
			}

			// Add button behaviour
			this.buttonMode = true;
			this.addEventListener(MouseEvent.CLICK, mouseClickHandler, false, 0, true);
		}

		// Public Methods:

		// Protected Methods:
		private function mouseClickHandler(e:MouseEvent):void {
			if(clickthroughURL != null) {
				navigateToURL(new URLRequest(clickthroughURL),"_blank");
			} else {
				trace("Clickthrough");
			}
		}
	}

}

Let’s quickly summarize what the ClickArea class is doing:

  • Imports the necessary Flash classes.
  • Is based on the Sprite class.
  • ClickArea’s constructor function requires two variables, the loaderInfo Object and the Stage. We will pass these in from our Banner document class.
  • Draws a transparent clickable area the width and height of the stage.
  • Attempts to get a clickthrough url out of the loaderInfo object and assign it to the clickthroughURL variable.
  • Adds behavior on mouse click that launches a clickthroughURL in a new window or outputs a trace if no URL is available. This is handy when testing in the Flash IDE.

Now open up your Banner class again and add import banner.util.ClickArea under your list of Flash class imports and update the init() function to instantiate the ClickArea and add it to the display list as shown below:

// Public Methods:
public function init():void {
	trace("Banner class initialized");

	// Create background
	var bg:Sprite = new Sprite();
	bg.graphics.beginFill(BG_COLOR);
	bg.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
	bg.graphics.endFill();
	addChild(bg);

	// Add Creative
	var creative:Creative = new Creative();
	addChild(creative);

	// Create clickable area
	var clickArea:ClickArea = new ClickArea(loaderInfo,stage);
	addChild(clickArea);
}

We’re adding the basic fundamentals of banner development into this class, but the real value here is that we are adding these to all our banners in one centralized class. Any common tasks you find yourself doing repeatedly in banners can be added in here to free up your time to craft the unique animation or interaction the banner creative has.


Step 18: Publishing Your .FLAs

With all of our code nicely organized, opening the individual .FLAs and publishing them is starting to feel like a hassle. The good news is, we can automate this as well. Go to your Project panel and check the tickbox beside each banner .FLA format (if you can’t see them in this list, click on the dropdown with the Gear icon and select Refresh) as shown below:

Now you can publish all of your banners to the /www/ folder you configured in Step 12 by clicking on the dropdown with the Gear icon and selecting Publish Project.


Step 19: HTML Presentation Page

The last element we need to complete to finish our banner project template is creating an HTML page to present them on so they can be shown to a client easily. Download SWFObject and place swfobject.js in the /www/ folder, then create a HTML file in the editor of your choice and write the code shown below:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>Banner Signoff Template</title>
	<style type="text/css" media="screen">
		body { padding:60px; }
		.banner { padding:0 40px 40px 0; float:left; display:block; }
	</style>
	<script src="swfobject.js" type="text/javascript"></script>
	<script type="text/javascript">
		var flashvars = { clickTag: "http://www.hornergraphic.com/" }
		swfobject.embedSWF("160x600.swf", "wide_skyscraper", "160", "600", "9", false, flashvars);
		swfobject.embedSWF("300x250.swf", "showcase", "300", "250", "9", false, flashvars);
		swfobject.embedSWF("728x90.swf", "leaderboard", "728", "90", "9", false, flashvars);
	</script>
</head>
<body>
	<div class="banner"><div id="wide_skyscraper"></div></div>
	<div class="banner"><div id="showcase"></div></div>
	<div class="banner"><div id="leaderboard"></div></div>
</body>
</html>

You can read more about how to use SWFObject in the online documentation, but let’s quickly cover the key things we’re doing here:

  • Declaring two css styles to create some space around the page and the individual banners.
  • Including swfobject.js, creating a test clickTag to pass in to our banners and writing the swfobject embed statements.
  • Defining a div structure and assigning a unique id to a div for SWFObject to dynamically replace with our SWF file.

Now save this file as index.html in the /www/ folder. You can now preview your banners in a web browser or upload this folder somewhere for your client to view:


Step 20: Review Your Project File Structure

Let’s finish by reviewing our populated folder structure and ensuring all files are in the appropriate place:

You now have a project template with:

  • A set of Photoshop templates to produce the artwork in.
  • A set of Flash templates to import library assets into and create timeline animations in.
  • A document class structure that allows you to implement functionality in one or all banner formats.
  • A way to compile all of your banners at once.
  • An HTML page to view all the banners together for yourself and your client.

Conclusion

This tutorial is really only the start. Identify recurring tasks in your banner projects and tailoring your project template to address them to make it speed up your workflow as much as possible. Extend upon it by including your favorite lightweight frameworks (TweenNano is great for scripted animation) and libraries so your favorite tools are at your fingertips when you start your next project.

If you use Subversion or some other kind of source control, this would be a great project to include in your repository so you can improve on it over time and check out the latest revision for each banner project you start.

Got ideas about how this could be improved or comments about issues that hamper your banner development? Join in the discussion below!

Model a High Rez Domed Fountain Structure in 3ds Max

In this intermediate level modeling tutorial, you will follow Ben Tate as he demonstrates how to create a deatailed domed structure and water fountain in 3ds Max.

A combination of both poly modeling and spline modeling techniques will be used to complete the structure and the water fountain. You will learn quick and efficient methods to build detailed molding pieces, utilizing simple extrude and bevel techniques, as well as combining spline profiles and the lathe modifier, as well as creating and positioning objects using the Array tool, and applying smoothing groups to your models.

Video 1

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 2

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 3

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 4

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

Quick Tip – Render Faster using the Windows Command Line with Maya

In this Quick Tip tutorial, you will learn how to batch render Maya scenes faster using the Windows command line, and in this way, maximize the amount of processing power you can get from your computer.

Step 1

First if you’re using Windows 7, and the latest version of Maya 2010, you need to set the path of the mayabatch to the systems’ Environment Variables. Right click on ‘Computer’ and select ‘Properties’. In the window that opens, click on ‘Advanced System Settings’.

Step 2

In the window that pops up, select the ‘Advanced’ tab on top, and then click on ‘Environment Variables’.

Step 3

Under ‘System Variables’, scroll and find the one with the name ‘Path’, select it, and click the ‘Edit’ button.

Step 4

In the window that comes up next to ‘Variable value:’, scroll to the end of the field, and add ‘;’ plus the path to your Maya directory (and its ‘bin’ folder). By default the directory is ‘C:\Program Files\Autodesk\Maya2010\bin’ Then click ok on all of the windows to close them.

Step 5

When rendering your file through the command line, the batch renderer will take all of the settings from the Maya file. These include settings in the render options, such as: the file name of the output files, image format, frame padding, start and end frames, renderable cameras, image size, and all of the other quality and render settings in the render set up. It will also take the different render layers (if you have them), and overall all the information will come from this file.

Step 6

Also the file’s output directory will be the same as specified in the project of the file.

Step 7

Now to open the command line, click on the ‘Start’ button, and then in the search field type ‘cmd’. The command line should show then show up. Click to open it. If you’re using XP, first click the ‘Start’ button, then select ‘Run’, and there type ‘cmd’ in the field.

Step 8

Then, an easy way to batch render a file is to navigate to the folder with the particular file you want to render. Let’s say the folder is ‘C:\Users\Pipera\Desktop\Project\My Projects\Project’, and in that folder there’s a file called ‘Concept_Scene_1’. To render it, first you need to enter the directory type ‘cd’, and the name of the folder (in this case it will be ‘cd C:\Users\Pipera\Desktop\Project\My Projects\Project’). Now to render the file, just type ‘Render FileName_and_Extension.mb (for Maya Binary). In this case the command line will look like this ‘Render Concept_Scene_1.mb’

Step 9

In general, when rendering from the command line, the batch renderer will always take the settings from the file. But there’s a way to edit the settings if you need to, without opening the file again and saving it. These settings are called ‘flags’, and are typed after the ‘Render’ command and before the file name. These flags won’t change your file, just the render that you’re going to output. To see all the different flags, open the command line and type ‘Render –h’

Step 10

The only settings that are going to change are the ones that are overridden with flags. Let’s say you need to change the size of your image, and you want to render with mental ray. In the command line type ‘Render –r mr –s 1 –e 125 Concept_Scene_1.mb’, where the ‘-r’ flag specifies which render to use (in this case ‘mr’ for mental ray), the ‘-s’ is the start frame of the animation, and the ‘-e’ is the end frame.

Step 11

Now for a more efficient way of rendering with Windows executable .bat files. These files are made and edited in Notepad. Let’s say that you want to render a file with mental ray. In Notepad write ‘Render –r mr Concept_Scene_1.mb’ and save the file, but make sure in the end of the name to put ‘.bat’, so that the file can save in a .bat format.

Step 12

Put the .bat file in the same folder as the file you want to render, and double click it to run the batch renderer.

Step 13

Using .bat files is great when you need to render several scenes that are in different directories. And what’s more, you can put different flags for each scene. It doesn’t matter where you put the .bat file, because the directories are listed within it. Also, the scenes will render consequently.

Step 14

With the ‘-rd’ flag, you can specify in which directory your files are going to be rendered.

Step 15

The ‘-rd’ flag can also be used for multiple files at the same time.

Step 16

Another highly useful flag is the ‘-cam’ flag, which lets you specify which camera to render from the scene.

Step 17

You can render as many cameras as you like from the same or different scenes, and also put different flags to make it even more efficient.

Step 18

Rendering different cameras is even better when combined with the ‘-rd’ tag, so each camera will be output into a different folder

Step 19

Remember that you can combine as many flags as you want to speed up your renders, and then you can view the commands when you type ‘Render –h’ in the command line.

Step 20

Some final useful tips for rendering from the command line: Don’t use spaces in the name of the files always put an ‘_’ instead; Make sure that the .bat files are saved with their extension after the name; If you want to stop the render process, just close the command line.

Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

Model, Texture, and Render the Legendary Katana in Maya – Day 3

In this 3 part Maya workflow tutorial you will learn how to model, texture, and render a Katana, the legendary Samurai sword. For the modeling portion, we will use Maya’s basic polygon editing tools, while UVlayout will be used to create the UVs, and of course Photoshop to create the textures. We will also briefly cover Mental Ray for rendering the final image.

This tutorial is Day 3 in a series – Go to Day 1, or Day 2.

Step 1

The last time we prepared our model for texturing, we laid out the UVs and made UV snapshots. Now we are going to make the textures and bump maps in Photoshop. I’m going to use textures from www.cgtextures.com, where you can find a great choice of high quality textures completely free. Note: Redistributing textures from cgtextures is prohibited, so anywhere I use a texture from their site, I’m going to put the directory and keywords for searching so you can download it yourself. Luckily the finished textures along with a model are allowed for distribution. So let’s get started .

Step 2

Start Photoshop and open the outUV_blade.jpg (the UV snapshot we made earlier).

Step 3

Create a new layer (Layer>New>Layer), or you can use the keyboard shortcut (Shift+Ctrl+N), or click on the little icon in the layer palette .

Step 4

Fill the new layer with 50% gray.

Step 5

Go to (Filter>Noise>Add noise). For amount enter about 20%, for distribution choose Uniform, and check Monochromatic.

Step 6

Go to (Filter>Blur>Motion Blur). For angle enter 90 degrees, and for distance enter 90 pixels. With this we have our base for the metal .

Step 7

Double click on the background layer and then click OK in the new window. With this we have unlocked this layer.

Step 8

Place the unlocked layer on top of the metal base layer, and choose Linear Dodge for the blending mode.

Step 9

Now we are going to make the Hamon (the pattern on the edge of the blade). For that we are going to use the Dodge tool.

Step 10

For the brush shape choose a round brush with radius of about 60px, 90% hardness, and for the range choose Highlights.

Step 11

Add the pattern by just clicking to create the circle pattern, but only about 1/4 to 1/3 of the circle should fall on the edge. Make sure there is no overlapping on the edge itself. Repeat this step all the way down and on the other side too.

Step 12

Take the Healing Brush tool.

Step 13

Make the brush size 20px and the hardness 20%.

Step 14

Press the alt key, and click on the inside of the circles to take a sample. Soften the point where to circles touch.

Step 15

Take the Burn tool. The default settings are fine, but just choose a bigger brush (something around 150px).

Step 16

With the burn tool, darken the UVs of the blood groove.

Step 17

Go to (Filter>Render>Lighting Effects). The shape of the light area, should cover the whole right part of the picture, so that the highlight is in front of the Hamon and the Hamon is lit evenly.

Step 18

Save the image in your textures folder as a jpg, with blade_color for the file name. Save the psd as well.

Step 19

Open the outUV_handle. This one is going to be easy. We will use a leather texture for the handle. You can use any leather texture you like, but if you would like to follow along, we are going to use a leather texture from cgtextures.com. It’s under fabric>leather, it’s a soft yellow leather texture, file name Leather0045. Keywords for searching “leather skin fine human” .

Step 20

If you downloaded the tileable one, duplicate it by holding the Alt key and dragging the layer, or by right clicking on the layer in the layer palette and going to “Duplicate layer”.

Step 21

Merge the two leather layers. In the layer palette, select the two layers, right click>Merge Layers.

Step 22

Save this image in your textures folder as a jpg, for file name enter handle_color.

Step 23

Duplicate the leather layer and go to (Image>Adjustments>Desaturate).

Step 24

Go to (Image>Adjustments>Brightness/Contrast), and tone down the brightness.

Step 25

Save this image in your textures folder as a jpg, the for file name enter handle_bump. Save the psd as well.

Step 26

Open the outUV_saya. For the texture here we are going to use a texture from cgtextures.com. It’s under paper>decorative paper, and it is a green creased paper. File name PaperDecorative0019. Keywords for searching, “paper folds fold crumpled crumples crumple wrinkle wrinkled wrinkles”.

Step 27

If you downloaded the tileable one, place it, and duplicate it for the length of the scabbard.

Step 28

If you go to viewing 100% of the image, you will notice that the texture creases are a bit big, and we want them a bit more subtle. Merge the duplicates and scale the merged layer down.

Step 29

Duplicate the merged layer again so it fills the scabbard UVs.

Step 30

Merge these layers, and duplicate the merged layer.

Step 31

Go to (Image>Adjustments>Brightness/Contrast) and lighten the layer a bit.

Step 32

Using the marquee tool, make rectangular selections along the length of the scabbard. Note: Holding the Shift key after you have made your first selection will allow you to make multiple selections.

Step 33

Press (Ctrl+Shift+i) to invert the selection, and then delete the selected area.

Step 34

Go to (Filter>Blur>Gaussian Blur), and enter 20px for the radius. These stripes will break up the monotony of the texture.

Step 35

Save this image in your textures folder as a jpg, for the file name enter Saya_color. Save the psd as well.

Step 36

Open the outUV_cloth.jpg. Here we are going to use a fabric weave texture from cgtextures.com. It’s under Fabric>Plain Fabric. File name FabricPlain0079. Keyword for searching “fabric weave woven”.

Step 37

Scale the fabric down to half of the bow using the scale tool (Edit>Free transform). Hold the shift key to scale proportionally.

Step 38

Go to (Image>Adjustments>Hue/Saturation) and darken the layer.

Step 39

Go to (Edit>Transform>Warp) and warp the layer to follow the curvature of the bow.

Step 40

Duplicate the layer and place it on the other half of the bow.

Step 41

Save this image in your textures folder as a jpg. For the file name, enter cloth_color.

Step 42

Merge the layer and duplicate the merged layer.

Step 43

Go to (Image>Adjustments>Brightness/Contrast) and lighten the layer. Desaturate it by going to (Image>Adjustments>Desaturate).

Step 44

Save this image in your textures folder as a jpg. For the file name, enter cloth_bump. Save the psd as well.

Step 45

Open Maya, and your most recent scene. You may have noticed that your meshes have hard edges after importing back from UVLayout. To fix that select everything, and under “Polygons”, go to (Normals>Soften Edge).

Step 46

For better previewing of your textures, add one light for now. Go to (Create>Lights>Spot Light).

Step 47

By default the light will be selected, so go to (Panels>Look trough Selected). Place the light so that it hits the edge of the blade at an angle. When you are finished with positioning the light, either click the perspective icon on the side or go to (Panels>Perspective>persp) to go back to perspective view.

Step 48

Open up the Hypershade by going to (Window>Rendering Editors>Hypershade).

Step 49

Drop an Anisotropic Maya shader, and double click it to open the Attribute Editor.

Step 50

In the Attribute Editor, click the checkered square next to color.

Step 51

In the Create render Node windows, choose File.

Step 52

Under the file attributes, click the folder icon next to image name, navigate to your textures folder, and choose blade_color.jpg.

Step 53

With the Hypershade open, select the blade mesh, then right click on the anisotropic shader in the Hypershade and go to Assign Material to Selection.

Step 54

We are now going to do the rendering with Mental ray, so go to (Window>Settings/Preferences>Plug-in Manager) and make sure “Mayatomr.mll” is checked.

Step 55

Press the Render the current frame button. Make sure you are using mental ray for rendering. Looks pretty good.

Step 57

Add another Anisotropic shader, and double click it to open the attribute editor.

Step 58

Click on the rectangle next to Color. In the Color Chooser, pick a color for the Tsuba. And press Accept.

Step 59

Select all of the pieces of the Tsuba .

Step 60

Assign the colored anisotropic material.

Step 61

Do a test render to see if you like the color. Looks good for now.

Step 62

In the Hypershade, click on Create Maya Nodes, and choose Create mental ray Nodes.

Step 63

Drop a mia_material, and assign it to the Habaki and Fuchi.

Step 64

Double click, the mia_mental ray material to open the Attribute editor. Click on the presets button and go to (copper>replace). Up the weight to 1, and change the Diffuse color to a lighter yellow.

Step 65

Do a test render. Looks good.

Step 66

Go back to Maya nodes, create a new Lambert material, and assign it to the cloth bow.

Step 67

In the Attribute editor, for ‘color’ choose ‘file’, and plug in the cloth_color.jpg image from your textures folder.

Step 68

In the Hypershade window, double click on the cloth Lambert to open the Attribute editor for it. Click on the checkered square next to Bump Mapping. Then choose file.

Step 69

For bump depth enter 0.2, this is usually a good starting point, but further tweaking will probably be required. Click on the triangle and square icon next to the Bump Value. This will show us the input.

Step 70

For Image name, plug in the cloth_bump.jpg image from your textures folder.

Step 71

In edit faces mode, select the end of the handle.

Step 72

Go to (Mesh>Extract), to extract this into a separate piece.

Step 73

Extrude this piece outward, to add some thickness to it.

Step 74

In the Hypershade window, drop a Blinn material, and assign it to the handle.

Step 75

Open the Attribute editor for the Blinn material, and for color, plug in the handle_color.jpg.

Step 76

Go to the Attributes for the Blinn material, and for Bump Mapping, plug in the handle_bump.jpg image file.

Step 77

In edit faces mode, select the tip of the scabbard, and add an edge loop if needed.

Step 78

Go to (Mesh>Extract), to extract this into a separate piece.

Step 79

Extrude it to add thickness.

Step 80

Select the rest of the scabbard, and open the UV texture editor.

Step 81

Go to edit faces mode.

Step 82

Select the faces of the piece you didn’t flatten.

Step 83

Go to (Mesh>Extract), to extract this in a separate piece.

Step 84

In the Hypershade, drop a Phong material, and assign it to the long piece of the scabbard.

Step 85

Open the Attribute editor for the Phong material, and for color, plug in the image file handle_color.jpg. If you like this green color, skip the next step.

Step 86

In the Attribute editor for the texture file, scroll down and open the Color balance options. Click on the Color Offset rectangle, and choose a color. This is a quick way to change the overall color of your texture. If you want more control over the color, you should adjust the color in Photoshop.

Step 87

In the Hypershade, drop another Phong material, and for color choose a similar color to that of the scabbard.

Step 88

Assign this material to all the pieces that were extracted before (the two pieces of the scabbard, and the one piece from the handle).

Step 89

Duplicate the cloth piece, and place it so that it overlaps the previous piece.

Step 90

Under “Animation”, go to (Create Deformers>Lattice).

Step 91

Right click near the Lattice, and choose Lattice Point.

Step 92

Move the points so that the top piece doesn’t intersect with the lower piece.

Step 93

After you are finished with tweaking the shape, select the piece, and go to (Edit>Delete by Type>History).

Step 94

Repeat this for the length of the handle.

Step 95

A little cleaning up and we are ready for the render setup. Select the bottom piece of the Scabbard, and Shift select the length of the Scabbard, than press the p key on your keyboard. With this, you have parented the tip piece with the length of the scabbard. Now whenever you select or move the length of the scabbard, the tip piece will move with it. Do the same with the top piece now.

Step 96

Select the center piece of the Tsuba. Shift select one of the circular ornaments, and press the p key on your keyboard.

Step 97

Select the parented circular ornament, then shift select the outer pipe, and press the p key on your keyboard.

Step 98

Select the remaining 3 ornament pieces, then shift select the outer pipe, and press the p key on your keyboard.

Step 99

Select all of the cloth pieces, the handle cap, and the handle, and then group them (Ctrl+g).

Step 100

With the group selected, Shift select the Fuchi, and then press the p key on your keyboard.

Step 101

Select the Fuchi, then Shift select the outer pipe, and press the p key on your keyboard.

Step 102

Select the Habaki, then Shift select the outer pipe, and press the p key on your keyboard.

Step 103

Select the outer pipe, then shift select the blade, and press the p key on your keyboard. Now when you select the blade, the whole sword is selected, and when you select the length of the Saya, the whole Saya is selected. Delete the history (Edit>Delete All by Type>History).

Step 104

Open the Outliner (Window>Outliner).

Step 105

Select the Blade in the perspective view, rename the highlighted part in the Outliner to Sword. Do the same for the Scabbard, but name it Saya.

Step 106

Go to (Create>CV Curve).

Step 107

In the side view create the profile for your backdrop.

Step 108

Move and duplicate the curve, for the width of your backdrop.

Step 109

Select the two curves, and then under “Surfaces”, go to (Surfaces>Loft).

Step 110

Create a polygon plane.

Step 111

Select the Spot light you created earlier, place it in the middle of the poly plane, and rotate it on the x axis by -90 degrees.

Step 112

Select the plane, then shift select the light, and press the p key on your keyboard.

Step 113

In the Hypershade, drop a surface shader, and for the Out Color, choose pure white.

Step 114

Apply the surface shader to the polyplane.

Step 115

Create a new Lambert material, and for color, choose a lighter gray.

Step 116

Assign the Lambert to the backdrop.

Step 117

Choose a position for rendering.

Step 118

Select the spot light, and in the attribute editor, enter 20 for Penumbra Angle . This will give a softer edge on the light.

Step 119

Select the light, and position it to the left and looking down on an angle at the sword.

Step 120

Duplicate the light setup, position it to the right, and looking almost perpendicular to the sword.

Step 121

Do a test render. As you can see, the image is a little blown out. You will have to tone down the lights. .

Step 122

Start by setting the intensity of the lights to 0.8. This might vary depending on the position of the lights, sword, color of the backdrop, and so on, so you will probably need to spend some time tweaking the intensity to get the desired result.

Step 123

Select the lights, and in the Attribute editor, scroll down until you find shadows and then Raytrace Shadow Attributes. Check the Use Ray Trace Shadows, and for Shadow Rays enter 16.

Step 124

When you are satisfied with your light setup, do a final render. Go to (View>Camera Settings>Resolution gate). So you can see exactly what area you will be rendering.

Step 125

Go to (Window>Rendering Editors>Render Settings).

Step 126

Under the quality tab, in Quality Presets, choose Production.

Step 127

Scroll down until you find the Raytracing options. For shadows enter 16.

Step 128

In the Common tab, under the Image size setting, enter your final resolution. Press the render button to render your final image.

Step 129

Here is the final result. Just for better presentation, I added a stand. You are welcome to create your own stand, or maybe a hand to hold the sword…or anything else you like!

This tutorial is Day 3 in a series – Go to Day 1, or Day 2.

Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

Create a Cool Smoking Text Effect using Fluid Mapping with Particle Flow

In this tutorial, you will model, light and texture some simple 3D text inside of 3dsmax. Then, using Particle Flow, the built-in particle system, along with the FumeFX plugin, you will simulate some convincing looking smoke to add a visual interest to your otherwise run of the mill 3D text .

Inside of the plugin UI you will learn what Fluid mapping is, and how to use it to your advantage. After the scene is completed you will render it out into different passes and then composite them back together inside of After Effects.

Video 1

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

Learn 3D From the Pros With CG Premium

Your most regularly updated source for computer graphics education just got a little more Incredible! Today we’re happy to announce that CGtuts+ is opening the doors to its brand new Premium program. Like our sister sites Psdtuts+, Vectortuts+, Audiotuts+, Nettuts+ and Aetuts+, our Premium Program will offer tutorials that go into even more detail than our regular free tuts, giving you an inside look on the techniques used by professionals in the field.

If you can’t wait to get started with your membership you can become a Premium member for as little as $9. You’ll also get instant access to 279 exclusive tutorials and 701 source files – and counting – available as part of our other Premium programs.

Want to know more?

We’ll still be publishing the same amount and quality of free tutorials, but once a week we’ll be publishing extra special ‘Premium’ content for members only. These tutorials will be a level above what we usually offer. With the help of Premium subscribers we are able to invest in higher-end, more in-depth tutorials showcasing thoughtfully developed techniques that will blow you and your clients away.

To kick-off CG Premium, members will instantly get access to a brand new tutorial exclusive for Premium members. In it, you’ll learn how to Model, UV, and Texture a Mac-10 Submachine Gun


This Premium Tutorial is Loaded with Tips

Over the course of this 10 hour monster of a tutorial, you will gain access to time saving professional gun modeling tricks and techniques that are universal to any 3d modeling application. We’ll give you an in-depth look at using the revolutionary and intuitive Headus UVLayout to quickly and effectively lay out all of the gun’s UVs, and finally, some tried tested and true texture painting techniques that use a careful balance between diffuse, specular, and bump maps to create realistic and convincing final metal textures.


Learn the Secret to High-End CG Weapon Creation

Follow professional CG artist, Ben Tate, as he demonstrates his entire process of modeling, UV mapping and texturing an extremely high quality Mac-10 submachine gun.

In the first part of this mammoth series, we will discuss a variety of efficient and innovative modeling techniques to create a medium density model. You will learn how to break the model down into into its respective parts in the blockout stage, and the approaches and tools to use when crafting the more complex shapes and parts.

We’ll also discuss where and where not to use subdivision modeling to speed things up further. This tutorial is intended for intermediate to advanced CG artists who are looking to take their skills up a notch, or maybe learn a new trick or two.

CG Tuts textured machine gun

That’s just the tip of the iceberg.

As soon as you join, you’ll instantly have access to 200+ tutorials and 700+ downloads from our Photoshop, Vector, Audio, After Effects, Computer graphics, and Web Development programs.

Here’s a full break-down:

1. Exclusive bonus tutorials teaching professional CG techniques

There are few industries where the techniques and methods of the professionals are so guarded in secrecy. We’ve lined up some of those professionals who are happy to break that unspoken oath of silence and teach you how things are done by the pros.

The tutorials are in-depth and challenging, yet clearly taught and easy to follow. Video lessons make learning impressive techniques easy, and each Premium tutorial comes with a full set of assets and source files you can use as you follow along. At less than the cost of a pizza, you’ll learn breathtaking techniques that will elevate your computer graphics projects to another level.

2. Exclusive source files for every tutorial

Great source files are hard to find, even if you pay big bucks for them. For $9 a month you’ll have access to the source files for every new tutorial we publish on the site, for as long as you’re a Premium member. As the network grows older this collection will increase to hundreds of files that you can use in your own projects, both personal and commercial. If you love all things CG, you’ll know how big this is!

3. Access to all Premium content, on all Tuts+ sites, past and present

While CG Premium members will have access to immediately download project files, you will also be able to plunder the archives of Psd Premium, Active Premium, Vector Premium, Audio Premium and Net Premium. You will immediately have access to over 200+ members-only tutorials and training videos, and over 700 download packs and source files for design, illustration, audio production and web development. You will also unlock the doors to all new Premium material published while you are a member. If another site goes Premium you will get access to Premium content for that site as well.

All for $9 a month, or $22 for 3-months, or $78 for one year (save $30).

4. You help keep CGtuts+ strong and healthy

Though we sell a small amount of advertising on the site, it only covers a tiny fraction of our costs. We pay at least $150 per tutorial, and have a salaried editor running the site. This adds up to thousands of dollars in costs each month. Our Premium members allow us to stay sustainable, to keep publishing great free content and to increase the quality of tutorials on the site. When you sign-up to Premium, you help Cgtuts+ stay strong and healthy into the future.

5. Premium isn’t for you? We’ll buy back your first month. It’s our 100% money back guarantee.

If you’re not 100% happy with Premium, we don’t want your money. That’s why we will buy back your subscription if you decide it’s not for you. You have one full month to make sure you’re getting value for money. Our friendly support team is on hand at all times to make good on our 100%, no-questions asked money-back guarantee.

Once you’re a member, login at the Tuts+ Dashboard and go to ‘Premium Content’ to claim your downloads.

Creating a Next-Gen Video Game Hot Rod: the Complete Workflow – Day 7

Now that we’ve wrapped up the UV’s in the previous part, it’s time to get to business with some serious normal map baking. You’ll be taken from a simple bake that shows an almost ideal baking scenario, to some very difficult examples such as the drivetrain and engine. Smoothing groups, UV splits/seams, cage setup and tweaking, and filtering settings, etc.. are all covered in detail. A few exceptionally difficult normal map problems, as well as their respective solutions, are also shown in this video.

This tutorial is Day 7 in a series – Go to Day 1, Day 2, Day 3, Day 4, Day 5, or Day 6.

Video 1

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 2

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 3

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 4

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

Video 5

Download

Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

This tutorial is Day 7 in a series – Go to Day 1, Day 2, Day 3, Day 4, Day 5, or Day 6.

Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

Quick Tip – Create Realistic Condensation on Glass with Maya Paint Effects

In this Maya Quick Tip tutorial, you will learn how to create realistic looking condensation any object, specifically cold glass, and then quickly render it for a nice polished final effect using Maya Paint Effects.

Step 1

Model your glass object. It could be a bottle, window, or anything that gives you the feeling of coldness.

Step 2

Switch to the “Rendering Menu” by pressing “F6″ on your keyboard, select the object, and then go to “Paint Effects > Make Paintable”.

Step 3

Open “Visor” by going to “Window > General Editors > Visor”.

Step 4

Select “Surface Bubbles” from the list.

Step 5

Start drawing the bubbles on the object’s surface. If the bubbles direction is reversed, simply undo, select the object, then go to “Edit NURBS > Reverse Surface Direction”, or “Normals > Reverse” if the object is made with Polygons. Now draw again. Note: To control the brush size, press “b” and hold while moving your mouse Left or Right.

Step 6

When you have finished drawing your bubbles, you may need to edit the following properties:

  • Sample Density: Increases or decreases the bubble density.
  • Surface Offset: Controls the distance between the object and the bubbles.
  • Smoothing: Smooths the bubbles path (underlying curve).
  • For me, the Density = 0.6, the Surface Offset = -0.010, and the Smoothing = 10.

    Step 7

    After that you can also add some tiny bubbles to fill in the empty area.

    Step 8

    Now you can render you scene using “Maya Software” or “Mental Ray”.

    For Maya Software Render, adjust the “Specular” and “Depth Shadow” attributes in the “Attribute Editor”. This will allow the “strokeSurfaceBubbles” brush to get a better render.

    For Maya Mental Ray Render, convert the Paint Effects to Polygons, and use “Mia_Material > Glass Presets” for the bubbles on the surface. You can use IBL to give reflections too if you like.

    Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.

    Unwrap a Cartoony Gatling Gun in Luxology Modo 401 – Basix

    In the second part of this Modo Basix tutorial, we will be continuing from where we left off in the modeling portion of the series, and going on to use many of Luxology Modo’s innovative UVW unwrapping tools to layout the UVs of our cartoony gatling gun model, and get it ready for texturing and materials. When you are finished, you should know everything that you need to get started unwrapping your own 3d models in this incredibly powerful package!!

    This tutorial is Day 2 in a series. Go to Day 1.

    Video 1

    Download

    Note: click the ‘Monitor’ icon to view tutorial in full-screen HD.

    Video 2

    Download

    This tutorial is Day 2 in a series. Go to Day 1.

    Don’t miss more CG tutorials and guides, published daily – subscribe to Cgtuts+ by RSS.