logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
Jun 29, 2011 Posted on Jun 29, 2011 in Hints and Tips | 0 comments

Hit the Target With a Deadly Homing Missile

This tutorial will show you a way to add homing missiles to the arsenal of your game.


Final Result Preview

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


Step 1: Set up the FLA Document

Create a new Flash document set for ActionScript 3.0. I’ll be using the dimensions of 600×400, and a frame rate of 30 FPS. Save the file with a name of your choice.

Create a .FLA document

Step 2: Create a Document Class

Besides the FLA, we also need to create a document class. Create a new Actionscript file, and add this code:

package
{
	import flash.display.Sprite;

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

		}
	}

}

Save this file in the same directory as our FLA. Name it Main.as.


Step 3: Link the Main Class with the FLA

In order to compile the code from the Main class, we need to link it with the FLA. On the Properties panel of the FLA, next to Class, enter the name of the document class, in this case, Main.

Link the Main class with the FLA

Then, save the changes on the FLA.


Step 4: Draw a Missile

We need a missile graphic to be displayed when shooting. You may import a bitmap or draw a shape right there on Flash. I’ll be using a tiny shape on this example.

Draw a missile shape or import a missile bitmap.

What’s important here is that you have to make the missile point straight to the right, since that’s the origin point for the rotation. So 0° means pointing straight to the right, -90° means upwards, 90° means downwards, and 180° points to the left. Later on we’ll need to rotate the missile according to its direction.


Step 5: Create a MovieClip for the Missile

Once you have the missile graphic, select it and press F8 to create a Movie Clip. Name it "Missile", make sure the the Registration Point is at the center, and tick the "Export for ActionScript" checkbox.

Create a MovieClip out of the missile you drew.

You’ll end up with a Missile MovieClip in the Library.

Missile MovieClip in the Library.

If you have a Missile instance on the Stage, delete it. We’ll be adding the Missile MovieClip by code.


Step 6: Aim

The first thing a homing missile needs to know is where the target is located. We’re going to set the rotation of the missile according to the position of the mouse cursor first. Let’s work with the enterFrame Event for a constant rotation update.

Add a Missile instance to the stage, I’m placing it at the center (300, 200). Then calculate the distance from the missile to the mouse cursor (I’m storing it in variables targetX and targetY). Finally, the missile’s angle will be the arc tangent of both points (targetX, targetY). The result you’ll get will be in radians, but the rotation works in degrees, so you’ll need to do the conversion by multiplying by 180/Pi. (To see why, check this article.)

import flash.events.Event;

public class Main extends Sprite
{
    private var missile:Missile = new Missile();

    public function Main()
    {
        addChild(missile);
        missile.x = 300;
        missile.y = 200;
        addEventListener(Event.ENTER_FRAME, playGame);
    }

    private function playGame(event:Event):void
    {
        var targetX:int = mouseX - missile.x;
        var targetY:int = mouseY - missile.y;
        missile.rotation = Math.atan2(targetY, targetX) * 180 / Math.PI;
    }
}

(Not sure what Math.atan2() is for? Check out this article on trigonometry.

If you Publish (Ctrl + Enter) the document at this point, you should be getting something like this:

Move your mouse near the missile to see it rotate.


Step 7: Seek

We got the rotation, now we need the movement. The missile has to seek the target, no matter whether it’s a steady or a moving target. What we’ll do is calculate the movement according to the current rotation of the missile. Let’s set a value for the speed, and make the missile chase after the mouse cursor.

We’ll include a couple of new variables to calculate the velocity (vx, vy). When the missile is pointing to the right, its angle is lower than 90° and higher than -90°, so it’s always lower than the absolute value of 90°. When it’s pointing to the left, its angle has an absolute value higher than 90°. This will determine vx in accordance to speed, then vy will be the difference of speed and vx.

private var speed:int = 10;

public function Main()
{
    addChild(missile);
    missile.x = 300;
    missile.y = 200;
    addEventListener(Event.ENTER_FRAME, playGame);
}

private function playGame(event:Event):void
{
    var targetX:int = mouseX - missile.x;
    var targetY:int = mouseY - missile.y;
    missile.rotation = Math.atan2(targetY, targetX) * 180 / Math.PI;
    //Velocity in x is relative to the angle, when it's 90° or -90°, vx should be 0.
    var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
    var vy:Number;//Velocity in y is the difference of speed and vx.
    if (missile.rotation < 0)
        vy = -speed + Math.abs(vx);//Going upwards.
    else
        vy = speed - Math.abs(vx);//Going downwards.

    missile.x += vx;
    missile.y += vy;
}

You’ll get a missile chasing your cursor.

You can use a different speed if you want.


Step 8: Create a Missile Launcher

Missiles don’t come out of thin air, they are shot out of missile launchers. Let’s make a MovieClip representing a cannon (I’ll use a simple rectangle), and name it Cannon. I’m going to add a Cannon instance by code, so I’m going to keep the stage empty.

Cannon MovieClip in the Library.

Step 9: Shoot

Now, instead of adding a missile, I’m just going to add a cannon, and a missile will be added at the cannon’s position when I click on the stage. We’ll add a Boolean to check if the missile has been shot, and also a new function for shooting after the click.

import flash.events.MouseEvent;

public class Main extends Sprite
{
    private var missile:Missile = new Missile();
    private var speed:int = 10;
    private var cannon:Cannon = new Cannon();
    private var missileOut:Boolean = false;//Has the missile been shot?

    public function Main()
    {
        addChild(cannon);
        cannon.x = 50;
        cannon.y = 380;
        addEventListener(Event.ENTER_FRAME, playGame);
        stage.addEventListener(MouseEvent.CLICK, shoot);
    }

    private function playGame(event:Event):void
    {
        if (missileOut)
        {
            var targetX:int = mouseX - missile.x;
            var targetY:int = mouseY - missile.y;
            missile.rotation = Math.atan2(targetY, targetX) * 180 / Math.PI;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }

    private function shoot(event:MouseEvent):void
    {
        if (!missileOut)
        {
            addChild(missile);
            swapChildren(missile, cannon);//missile will come out from behind cannon
            missileOut = true;
            missile.x = cannon.x;
            missile.y = cannon.y;
        }
    }

This is what you’ll get:

This doesn’t look nice. We have to either make the cannon rotate as well, or force the missile to go upwards right after being shot. Since option #1 is the easiest approach, we’ll take option #2.


Step 10: Less Precision for Better Looks

If the cannon is vertical, we would expect the missile to launch upwards and then get on track towards its target. The approach I’ll use to achieve this is to give the missile a starting angle of -90° (pointing upwards), and smoothly rotate to get on track to the mouse cursor. We’ll add an ease variable to determine the smoothness or sharpness of the rotation. Then we’ll create another variable to keep track of the actual rotation that points straight to the target, while the missile’s rotation will change according to the ease we set (ease = 1 will behave just like before, anything higher will make a smoother turn).

Since half of the rotation values are negative, in some cases we’ll need to calculate them against 360 to get the actual difference between the target angle and the missile’s rotation.

private var ease:int = 10;

public function Main()
{
    addChild(cannon);
    cannon.x = 50;
    cannon.y = 380;
    addEventListener(Event.ENTER_FRAME, playGame);
    stage.addEventListener(MouseEvent.CLICK, shoot);
}

private function playGame(event:Event):void
{
    if (missileOut)
    {
        var targetX:int = mouseX - missile.x;
        var targetY:int = mouseY - missile.y;
        var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
        if (Math.abs(rotation - missile.rotation) > 180)
        {
            if (rotation > 0 && missile.rotation < 0)
                missile.rotation -= (360 - rotation + missile.rotation) / ease;
            else if (missile.rotation > 0 && rotation < 0)
                missile.rotation += (360 - rotation + missile.rotation) / ease;
        }
        else if (rotation < missile.rotation)
            missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
        else
            missile.rotation += Math.abs(rotation - missile.rotation) / ease;

        var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
        var vy:Number;
        if (missile.rotation < 0)
            vy = -speed + Math.abs(vx);
        else
            vy = speed - Math.abs(vx);

        missile.x += vx;
        missile.y += vy;
    }
}

private function shoot(event:MouseEvent):void
{
    if (!missileOut)
    {
        addChild(missile);
        swapChildren(missile, cannon);//missile will come out from behind cannon
        missileOut = true;
        missile.x = cannon.x;
        missile.y = cannon.y;
        missile.rotation = -90;//missile will start pointing upwards
    }
}

Check it out:

Notice what happens when you move your mouse out of the SWF, and how this is different from the previous example.


Step 11: Missile Hits, Missile Explodes

Besides the Missile Movie Clip, we need an explosion animation. In my case, I’ll make a separate MovieClip with a simple tween of a circle that expands. I’m exporting it as Explosion. Press O to select the Oval Tool, and hold Shift while drawing the oval to get a circle.

The circle inside its own Movie Clip with a Bevel filter.

For a nicer visual effect, I’ll put the circle inside another Movie Clip of its own, and give it a Bevel filter to get a darker color at the bottom and a lighter color at the top. Next, I’ll go to frame 10 and press F6 to create a Keyframe, then right-click between frame 1 and 10 and create a Classic Tween. Back on frame 10, press Q to select the Free Transform Tool and enlarge the circle.

Enlarge the circle in a Classic Tween.

Then, create another Classic Tween to frame 20, I’ll add a Blur filter effect.

Add a Blur filter in a Classic Tween.

Finally, make it disappear in a last Classic Tween to frame 30 with an Alpha color effect going to 0.

Alpha color effect set to 0 in a Classic Tween.

Step 12: Clean Up the Stage

The explosion animation has to be removed after it finishes, or it will loop indefinitely. Add a new layer and press F6 on the last frame, then press F9 to open the Actions panel, and add this code:

stop();<br />parent.removeChild(this);

This will make the Explosion instance remove itself after the animation is done.

The Explosion instance will remove itself.

Step 13: Explode

Now when the missile meets the cursor, we’ll replace it with an Explosion instance. We just need to add a new conditional in the playGame() function.

private function playGame(event:Event):void
{
    if (missileOut)
    {
        if (missile.hitTestPoint(mouseX, mouseY))
        {
            var explosion:Explosion = new Explosion();
            addChild(explosion);
            explosion.x = missile.x;
            explosion.y = missile.y;
            removeChild(missile);
            missileOut = false;
        }
        else
        {
            var targetX:int = mouseX - missile.x;
            var targetY:int = mouseY - missile.y;
            var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
            if (Math.abs(rotation - missile.rotation) > 180)
            {
                if (rotation > 0 && missile.rotation < 0)
                    missile.rotation -= (360 - rotation + missile.rotation) / ease;
                else if (missile.rotation > 0 && rotation < 0)
                    missile.rotation += (360 - rotation + missile.rotation) / ease;
            }
            else if (rotation < missile.rotation)
                missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
            else
                missile.rotation += Math.abs(rotation - missile.rotation) / ease;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }
}

Take a look:


Step 14: Something Else to Blow Up

Chasing after the mouse cursor was entertaining, but it’s pointless in a game; we need to make a target. I’m going to draw a bunch of circles to form a Target Movie Clip.

Create and export a Target Movie Clip.

Step 15: Shoot the Target

Now we’ll add a Target instance for the missile to have a more tangible objective. So we’ll replace any reference of the mouse cursor for the target’s position. Also, we won’t be testing for a hit point, but an object.

private var target:Target = new Target();

public function Main()
{
    addChild(cannon);
    cannon.x = 50;
    cannon.y = 380;
    addEventListener(Event.ENTER_FRAME, playGame);
    stage.addEventListener(MouseEvent.CLICK, shoot);addChild(target);
    target.x = 550;
    target.y = 50;
}

private function playGame(event:Event):void
{
    if (missileOut)
    {
        if (missile.hitTestObject(target))
        {
            var explosion:Explosion = new Explosion();
            addChild(explosion);
            explosion.x = missile.x;
            explosion.y = missile.y;
            removeChild(missile);
            missileOut = false;
        }
        else
        {
            var targetX:int = target.x - missile.x;
            var targetY:int = target.y - missile.y;
            var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
            if (Math.abs(rotation - missile.rotation) > 180)
            {
                if (rotation > 0 && missile.rotation < 0)
                    missile.rotation -= (360 - rotation + missile.rotation) / ease;
                else if (missile.rotation > 0 && rotation < 0)
                    missile.rotation += (360 - rotation + missile.rotation) / ease;
            }
            else if (rotation < missile.rotation)
                missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
            else
                missile.rotation += Math.abs(rotation - missile.rotation) / ease;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }
}

private function shoot(event:MouseEvent):void
{
    if (!missileOut)
    {
        addChild(missile);
        swapChildren(missile, cannon); //missile will come out from behind cannon
        missileOut = true;
        missile.x = cannon.x;
        missile.y = cannon.y;
        missile.rotation = -90;//missile will start pointing upwards
    }
}

The hitTestObject() method actually only checks for an overlap between the bounding boxes of the two objects (i.e., the blue boxes that appear when you click an instance of the object in the stage), so watch out for that; it’s not pixel-perfect collision detection. However, it does the job just fine here.

You may try placing the target at different locations, as well as the cannon.


Step 16: Moving Target

We already saw that the missile will chase a moving target, such as the mouse cursor, so now let’s make the Target instance move a little.

This isn’t realistic physics, I’m just going to make the target bounce vertically. I’ll pick a reference point as the ground level, and add a gravity value to affect the target. And to make it more dynamic, I’ll increase the missile speed to 15.

private var floor:int = 385;
private var gravity:Number = 0.5;
private var targetVY:Number = 0;//Current vertical velocity of the target

public function Main()
{
    addChild(cannon);
    cannon.x = 50;
    cannon.y = 380;
    addEventListener(Event.ENTER_FRAME, playGame);
    stage.addEventListener(MouseEvent.CLICK, shoot);addChild(target);
    target.x = 550;
    target.y = 50;
}

private function playGame(event:Event):void
{
    if (missileOut)
    {
        if (missile.hitTestObject(target))
        {
            var explosion:Explosion = new Explosion();
            addChild(explosion);
            explosion.x = missile.x;
            explosion.y = missile.y;
            removeChild(missile);
            missileOut = false;
        }
        else
        {
            var targetX:int = target.x - missile.x;
            var targetY:int = target.y - missile.y;
            var rotation:int = Math.atan2(targetY, targetX) * 180 / Math.PI;
            if (Math.abs(rotation - missile.rotation) > 180)
            {
                if (rotation > 0 && missile.rotation < 0)
                    missile.rotation -= (360 - rotation + missile.rotation) / ease;
                else if (missile.rotation > 0 && rotation < 0)
                    missile.rotation += (360 - rotation + missile.rotation) / ease;
            }
            else if (rotation < missile.rotation)
                missile.rotation -= Math.abs(missile.rotation - rotation) / ease;
            else
                missile.rotation += Math.abs(rotation - missile.rotation) / ease;

            var vx:Number = speed * (90 - Math.abs(missile.rotation)) / 90;
            var vy:Number;
            if (missile.rotation < 0)
                vy = -speed + Math.abs(vx);
            else
                vy = speed - Math.abs(vx);

            missile.x += vx;
            missile.y += vy;
        }
    }
    targetVY += gravity;
    target.y += targetVY;
    if (target.y > floor)
    {
        target.y = floor;
        targetVY = -18;
    }
}

If you Publish this now, you should be getting a moving target.


Conclusion

Whether you want an accurate homing missile, or you’d prefer a smooth animation, you can get both results based on this example. Now you’ve got a new weapon to add in your arsenal, maybe you could try making a Worms-like game, or even use the algorithm on something other than a missile, like some weird mosquito that follows your character.

I hope you’ve found this tutorial useful. Thanks for reading!



View full post on Activetuts+

Jun 28, 2011 Posted on Jun 28, 2011 in Hints and Tips | 1 comment

Introduction to ByteArray

ByteArray is an extremely powerful Class that can be used for many things related to data manipulation, including (but not limited to) saving game data online, encrypting data, compressing data, and converting a BitmapData object to a PNG or JPG file. In this introduction, we’ll use the ByteArray class to take a native AS3 object and encode it to a string that could be saved to a server for later recovery, then decode it later.

In previous tutorials we’ve seen how to use XML and JSON to encode data in a textual (String) format. However, both XML and JSON are designed to be human-readable, and as a result they’re much longer than they need to be. It can also be tricky to convert certain types of AS3 object to either format. ByteArray has some truly advanced features, but to start with, we’ll just look at one simple one: it makes it very easy to turn an AS3 object into a String.


Final Result Preview

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

When you paste an encoded ByteArray string into the TextField and click the Load button, it will decrypt it, and show the object properties saved in it. You can try the following encoded ByteArrays; copy-paste them into the TextField and click the Load button to see what I am talking about:

//This ByteArray will show my data (This is the default ByteArray loaded)
CgsBFW9jY3VwYXRpb24GB0NUTw93ZWJzaXRlBiFodHRwOi8vaWt0LmNvLmlkCW5hbWUGDVRhdWZpawE=
//This ByteArray will show my current thought
CgsBIWZvb2RfZm9yX3Rob3VnaHQGgnVJIGFtIHRoaW5raW5nIG9uIHNoYXJpbmcgdGhlIHRlY2huaXF1ZSBpIHVzZWQgdG8gbWFrZSBhIEZ1bGwgRmxhc2ggRHluYW1pYyBXZWJzaXRlIFNFTyBGcmllbmRseSBmb3IgbXkgbmV4dCBUdXRvcmlhbCBpbiBBY3RpdmVUdXRzKy4uLiA8dT5XaGF0IGRvIHlvdSB0aGluaz88L3U+IDxiPmlzIGl0IGEgZ29vZCBpZGVhPC9iPj8B
//This ByteArray will talk about Flash and SEO and my experience with them
CgsBEXF1ZXN0aW9uBoEDPGI+PHU+Q2FuIGEgZnVsbHkgZHluYW1pYyBGbGFzaCBXZWJzaXRlIGJlIFNFTyBmcmllbmRseTwvdT48L2I+Pz8NYW5zd2VyBoM/SXQgY2FuLCBoZXJlIGlzIHRoZSBwcm9vZiwgPGEgaHJlZj0naHR0cDovL3d3dy5nb29nbGUuY28uaWQvc2VhcmNoP3E9Zmxhc2grc2VvJmllPXV0Zi04Jm9lPXV0Zi04JmFxPXQnIHRhcmdldD0nX2JsYW5rJz5odHRwOi8vd3d3Lmdvb2dsZS5jby5pZC9zZWFyY2g/cT1mbGFzaCtzZW8maWU9dXRmLTgmb2U9dXRmLTgmYXE9dDwvYT4sIGlrdC5jby5pZCBpcyByYW5rZWQgIzYgb3ZlciB0aGVyZQE=

Step 1: Create New ActionScript Project

Create New ActionScript Project

Within the ‘Flash Builder’ window :

  1. Open Flash Builder 4
  2. Click the File Menu
  3. Hover to New
  4. Click ActionScript Project

Step 2: New ActonScript Project Setup

ActionScript Project Setup

Within the ‘New ActionScript Project’ window :

  1. Type ‘TUTORIAL_ByteArray’ into Project name field
  2. Please remember where you save your project
  3. Click ‘Finish’ button

Step 3: Base64.as

Copy Base64.as into your project ‘com’ directory.

Copy Base64.as file into 'com' directory
  1. Create a new ‘com’ directory inside your source directory.
  2. Download the Base64.as file from the source download.
  3. Put the file into the newly created ‘com’ directory.

Base64.as will come in useful later. It’s by Steve Webster, who used to reside at dynamicflash.com (he left the Flash community a couple of years ago).


Step 4: Necessary Classes

Import all Classes used in this project

In TUTORIAL_ByteArray class (which is the main class), please import the following Classes for this tutorial:

package
{
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.events.MouseEvent;
	import flash.utils.ByteArray;
	import com.Base64;

	public class TUTORIAL_ByteArray extends Sprite
	{
		public function TUTORIAL_ByteArray()
		{

		}
	}
}

Step 5: Getting used to Flash Builder I

Trace the 'Hello World' message

Add the following code inside TUTORIAL_ByteArray Constructor for a very simple test.

public function TUTORIAL_ByteArray()
{
	var _test:String = "Hello world!";
	trace(_test);
}

Press F11 key to run this project, you should get the message inside the Console Window.


Step 6: Getting used to Flash Builder II

Local variable only available inside the function it is created

Now let’s try to trace the message inside _test variable, but this time we will do it from another function:

public function TUTORIAL_ByteArray()
{
	var _test:String = "Hello world!";
	TestFunction();
}
private function TestFunction():void{
	trace(_test);
}

Press CTRL+S to save your project. An error detected after you saved your project; this is because a variable which has been declared inside a function will not be available for any other function. So for this case, we need to declare the _test variable outside:

public function TUTORIAL_ByteArray()
{
	TestFunction();
}
private function TestFunction():void{
	trace(_test);
}
private var _test:String = "Hello world!";
Private variables are available to all function inside the same class

Step 7: Necessary Private Variables

Create all private variables for this project

Please add the following private variables for this project:

public function TUTORIAL_ByteArray()
{
	TestFunction();
}
private function TestFunction():void{
	trace(_test);
}
private var _test:String = "Hello World!";
private var _loadButton:TextField;
private var _inputField:TextField;
private var _testObject:Object;
private var _testByteArray:ByteArray;

Step 8: UI

Let’s create a simple user interface for this project.

a Simple user interface

Now that we need to display something into our project, we need to declare our stage sizes (Check Line 13).

Rename our TestFunction into InitUI function, and put the following line of codes inside. Please read the explanation commented inside the code.

[SWF(width="550", height="400", frameRate="60", pageTitle="Tutorial ByteArray")]
public class TUTORIAL_ByteArray extends Sprite
{
	public function TUTORIAL_ByteArray()
	{
		InitUI();
	}
	private function InitUI():void{
		//Initialize our TextFields so that we can use them
		_loadButton = new TextField();
		_inputField = new TextField();

		//Give a defaultTextFormat for both of them (Tahoma at 11pt, colored 0x777777)
		_loadButton.defaultTextFormat = _inputField.defaultTextFormat = new TextFormat("Tahoma", 11, 0x777777);

		//Give both of them a border
		_loadButton.border = _inputField.border = true;

		//Set the autosize for our Load Button , so that it will automatically shrink / grow to fit the text inside
		_loadButton.autoSize = TextFieldAutoSize.LEFT;

		//Set the selectable of our Load Button to false, so that user cannot select the text in it
		_loadButton.selectable = false;

		//Set the multiline and wordWrap of our Input Field to true, so that a long text will automatically wrapped to the next line
		_inputField.multiline = _inputField.wordWrap = true;

		//Enable user to type something into our Input Field, by setting this type property
		_inputField.type = TextFieldType.INPUT;

		//Put some text into Both of them
		_loadButton.text = "Load";
		_inputField.text = "";

		//Add both of them into stage, so that they are visible to our visitors
		addChild(_inputField);
		addChild(_loadButton);

		//Position our Input Field and make it bigger
		_inputField.x = 25;
		_inputField.y = 25;
		_inputField.width = 200;
		_inputField.height = 150;

		//There is a reason why i did this, so that the Load Button is located directly below our Input Field
		//So you can position the Input Field anywhere you like, as long as there is this code, the Load Button will stick below the Input Field
		_loadButton.y = _inputField.y + _inputField.height;
		_loadButton.x = _inputField.x;
	}

Press F11 to run this project and see the simple user interface we have created.


Step 9: Enable Interactivity

Type into the field and click the load button

Please read the explanation commented inside the code

	_loadButton.y = _inputField.y + _inputField.height;
	_loadButton.x = _inputField.x;

	//Add an Event Listener for our _loadButton, so whenever the user clicks this button,
	//Flash will call _loadButton_CLICK() Method
	_loadButton.addEventListener(MouseEvent.CLICK, _loadButton_CLICK, false, 0, true);
}
//This method will be called whenever user click the _loadButton
private function _loadButton_CLICK(Events:MouseEvent = null):void{
	//Get anything that the user input and save them into our _test variable
	_test = _inputField.text;

	//Trace the _test variable
	trace("User input the following message : " + _test);
}

Press F11 to run this project; try typing something into the _inputField and then click the _loadButton. This is the most basic technique of getting a variable from our user and storing it into our private variable.


Food for Thought

We have finally reach our most important steps in this project, but before we continue let me provides a mental stimulus for thinking. Currently in our project, we are capable of getting a String and storing it in our private variable. But it is only a string; how about if I want a user to type in something inside _inputField so that I can get an Object from it? What should the user type? The answer is an ‘Encoded Base64 ByteArray’


Step 10: Introduction to ByteArray

Output from our ByteArray

We will proceed slowly this time, so that you will understand the ByteArray class and be able to create your own data manipulation and apply it to your own projects. Please read the explanation commented inside the code:

public function TUTORIAL_ByteArray()
{
	InitUI();
	CreateByteArray();
}
private function CreateByteArray():void{
	//Initialize our _testObject variable, so that we can populate many dynamic properties and store String data in it (we will load them later whenever user clicked the _loadButton)
	_testObject = new Object();
	_testObject.name = "Taufik";
	_testObject.website = "<a href='http://ikt.co.id'>http://ikt.co.id</a>";
	_testObject.occupation = "CTO";

	//Initialize our _byteArray variable, so that we can start converting object into a ByteArray
	_testByteArray = new ByteArray();

	//Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it? :) )
	_testByteArray.writeObject(_testObject);

	//Lets see if everything works properly
	trace("Our first ByteArray created :: " + _testByteArray.toString());
}

Press F11 to run this project. See how simple it is, this ByteArray is an extremely powerful class and yet it is not hard at all. We’ve taken a native AS3 Object and converted it to Action Message Format.

Before sending the data to our PHP Script using the GET method, we should convert it into a Base64 String. This is because Base64 can be carried by XML (and by HTML).


Step 11: Encoding ByteArray into Base64 String

a Base64 String representation of our Byte data

Please read the explanation commented within the code.

private function CreateByteArray():void{
	//Initialize our _testObject variable, so that we can populate many dynamic properties and store String data in it
	//(we will load them later whenever user clicks the _loadButton)
	_testObject = new Object();
	_testObject.name = "Taufik";
	_testObject.website = "<a href='http://ikt.co.id'>http://ikt.co.id</a>";
	_testObject.occupation = "CTO";

	//Initialize our _byteArray variable, so that we can start converting object into a ByteArray
	_testByteArray = new ByteArray();

	//Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it? :) )
	_testByteArray.writeObject(_testObject);

	//Encode the ByteArray into Base64 String (so that we can send them via PHP or copy the text to notepad), again IT IS VERY SIMPLE!
	var encoded:String = Base64.encodeByteArray(_testByteArray);

	//Put the encoded Base64 String into our _inputField (so that we can copy them into notepad)
	_inputField.text = encoded;
}

Press F11 to run this project. If converting an Object into a ByteArray is simple, converting the Byte value of our data into Base64 String is as simple, thanks to Base64.as.


Step 12: Converting Encoded Base64 String into Object

Converting a Base64 String into Object and displaying its properties and values

We will try to decode the entered Base64 String into an Object whenever the user clicks the _loadButton, change our _loadButton_CLICK function. Please read the explanation commented inside the code:

private function _loadButton_CLICK(Events:MouseEvent = null):void{
	//We have to catch any Errors
	try{
		//We decode our encoded Base64 String into a ByteArray, so that we can retrieve our Object back
		var DecodedByteArray:ByteArray = Base64.decodeToByteArray(_inputField.text);

		//If converting an Object into ByteArray is simple, retrieving an Object from ByteArray is as simple as this
		var LoadedObject:Object = DecodedByteArray.readObject();

		//Prepare to output all properties and their values inside the LoadedObject
		var Output:String = "";
		for (var VarName:String in LoadedObject){
			Output += VarName + " : " + LoadedObject[VarName] + "<br>";
		} 

		//Output them into our _inputField
		_inputField.htmlText = Output;
	}catch(err:Error){
		_inputField.text = "Please input an Encoded ByteArray into this TextField before clicking the 'Load' Button. Error message :: " + err.message;
	}
}

Press F11 to run this project. We get our encoded Base64 String of our _testObject inside our _inputField; click the _loadButton to see our project convert this Base64 String back and display all of its properties and values. You can try to copy and paste the Base64 Strings at the beginning of this tutorial and read all of my messages.


Conclusion

The ByteArray Class is an extremely powerful Class, and yet it is very simple to use. I have seen many great Flash apps out there utilizing this ByteArray to perform so many mind blowing data manipulation, such as those kinds I mentioned at the beginning of this tutorial. I have heard many Flash game programmers utilize XML to save their visitors’ ‘Save Game Data’, but as we all already know, XML is one hell of a very complicated class; with ByteArray I can save something like this EASILY.

private function CreateByteArray():void{
	_testObject = new Object();
	_testObject.name = "Taufik";
	_testObject.website = "<a href='http://ikt.co.id'>http://ikt.co.id</a>";
	_testObject.occupation = "CTO";
	_testObject.level = 99;

	//Get the state of this Game Character Inventory
	var _inventory:Array = new Array({item_id:5, amount:1}, {item_id:85, amount:1}, {item_id:42, amount:5});
	_testObject.inventory = _inventory;

	//Get what is the skill they already level up
	var _skill:Array = new Array({skill_id:1, level:0}, {skill_id:2, level:1});
	_testObject.skill = _skill;

	//Initialize our _byteArray variable, so that we can start converting object into a ByteArray
	_testByteArray = new ByteArray();

	//Convert the Object into Byte Array, This is how you do it, to convert an Object into a ByteArray, IT IS SIMPLE isnt it? :) )
	_testByteArray.writeObject(_testObject);

	//Encode the ByteArray into Base64 String (so that we can send them via PHP or copy the text to notepad), again IT IS VERY SIMPLE!
	var encoded:String = Base64.encodeByteArray(_testByteArray);

	//Put the encoded Base64 String into our _inputField (so that we can copy them into notepad)
	_inputField.text = encoded;
}

Yeah, something this complicated only takes a couple line of codes, imagine the horror of saving this data using XML and retrieving them back for further use. All in all I have to say that with Byte data manipulation you can achieve a lot of things, and some might be the solution you have been looking for all this time.

I hope you have found this tutorial useful. Thanks for reading!



View full post on Activetuts+

Jun 27, 2011 Posted on Jun 27, 2011 in Hints and Tips | 1 comment

Gravity in Action

The study of forces is of central interest in dynamics, the study of causes of motion and changes in motion. Gravitational force is one example; it is this which causes satellites to revolve around planets and us to stay on the ground.

In this tutorial, we will build a simulation of such phenomenon and be able to observe, experiment and play with particles on the scene.

Among all particles generated, one main particle will attract others. As these particles move towards the main one, users can click on this main particle to drag it around, causing these particles to redirect their course. These particles will stop moving as they collide with the edge of main ball, but they won’t overlap each other.

The structure of this tutorial is arranged in a manner where a brief theory in Physics in delivered before introducing the implementation of the simulation. Enjoy!


Final Result Preview

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

Click and drag the big green circle to move it around, and watch how the little blue circles react.


Step 1: Gravitational Force, Formula

Formula of attractive force

First, a Physics preface. The attractive gravitational force between any two objects is expressed through the following formula:

F: attractive force being exerted onto object of interest (p2) by
an arbitrary particle (p1).

G: Gravitational constant

m1: mass of p1

m2: mass of p2

r: distance between p1 and p2

Take special note of the following:

  1. The relationship between gravity and distance: F is inversely proportional to the square of the distance separating the two particles. This means the closer A and B are to each other, the higher the attractive force between them and vice versa. If you double the distance, the force goes down to a quarter of its original value.
  2. Value of gravitational constant, G, is scientifically 6.67259 x 10-11 N * m2 / kg2. However, 500 will substitute this value in Flash environment.
  3. We can relate particle’s width to their mass. For this example, I’ve defined a particle’s mass to be half of its radius.

Step 2: Newton’s 2nd Law, Equation

In order to translate force into kinematics, we need to calculate particle’s acceleration. The famous equation by Sir Isaac Newton is shown below:

formula f=ma

F: gravitational force being exerted onto object of interest (p2)

m: mass of object of interest (p2)

a: acceleration of object of interest (p2) under influence of F

Here, the implication is that a higher force applied onto particle A results in a higher acceleration (assuming its mass stays the same). This acceleration will change the particle’s velocity.


Step 3: Starting Project

Implementation will be done in FlashDevelop IDE. Build your project file.

  1. Start a new Project, PROJECT > NEW PROJECT…
  2. Select from pop up window, AS3 PROJECT
  3. Name your project. In my case, Attractor
  4. Select your project location

See this guide for an introduction to FlashDevelop.


Step 4: Classes You Need

There are 4 classes to create in folder \src\: Main.as, Vector2D.as, Ball.as & Math2.as. It is advisable that you download all these files from the source package and try to map them against steps to come to get a general understanding of the mechanism before modifying them. Their roles are expressed as below:

Class Name Purpose of Organisation
Main.as Class to create the balls visually and to attach animation to events.
Vector2D Class that holds all vector manipulation functions.
Ball Class that contains functions to visually generate a ball, implements dynamics and kinematics of a ball.
Math2 Static class that holds a function to facilitate randomizing the initial location of balls.

Step 5: Randomising Values

Lets talk about the Math2 class first. The function below will help to generate a random number within the specified range. Accepts two inputs, minimum limit and maximum limit in range.

public static function randomiseBetween(range_min:int, range_max:int):int
{
	var range:int = range_max - range_min;
	var randomised:int = Math.random() * range + range_min;
	return randomised;
}

Step 6: Vector2D, Getters and Setters

The bulk of Math used is located in Vector2D. This tutorial assumes a level of familiarity in vector analysis in the users. The functions below are generally used to get and set vector components, plus a method to reset all components to zero. In any case, if you are uncomfortable with Vectors, visit a great post on Euclidean Vectors by Daniel Sidhion.

public function Vector2D(valueX:Number, valueY:Number)
{
	this._x = valueX;
	this._y = valueY;
}
public function set vecX(valueX:Number):void
{
	this._x = valueX;
}
public function get vecX():Number
{
	return this._x
}
public function set vecY(valueY:Number):void
{
	this._y = valueY;
}
public function get vecY():Number
{
	return this._y
}
public function setVector(valueX:Number, valueY:Number):void
{
	this._x = valueX;
	this._y = valueY;
}
public function reset():void
{
	this._x = 0;
	this._y = 0;
}

Step 7: Vector2D, Operations

The major uses of Vector2D lie in the following functions, which:

  • obtain the magnitude of vector
  • obtain the angle made by vector in relation to the origin
  • obtain the vector direction of vector
  • perform simple vector operations of addition, subtraction and scalar
    multiplication
public function getMagnitude():Number
{
	var lengthX:Number = this._x;
	var lengthY:Number = this._y;
	return Math.sqrt(lengthX * lengthX +lengthY * lengthY);
}
public function getAngle():Number
{
	var lengthX:Number = this._x;
	var lengthY:Number = this._y;
	return Math.atan2(lengthY, lengthX);
}
public function getVectorDirection():Vector2D
{
	var vectorDirection:Vector2D = new Vector2D(this._x / this.getMagnitude(), this._y / this.getMagnitude());
	return Vector2D(vectorDirection);
}
public function minusVector(vector2:Vector2D):void
{
	this._x -= vector2.vecX;
	this._y -= vector2.vecY;
}
public function addVector(vector2:Vector2D):void
{
	this._x += vector2.vecX;
	this._y += vector2.vecY;
}
public function multiply (scalar:Number):void
{
	this._x *= scalar;
	this._y *= scalar;
}

Step 8: Ball.as Drawing

The Ball class is where all the interesting operations take place. To begin our animation, we need to draw a ball and set several kinematics- and dynamics-related variables. The function to draw a ball is as below:

private function draw(radius:Number, color:uint) :void
{
	graphics.beginFill(color, 1);
	graphics.drawCircle(0, 0, radius);
	graphics.endFill();
}

Step 9: Ball.as Private Variables

The mentioned several kinematics and dynamics related variables are stated as below:

private var _disp:Vector2D;	//displacement vector, relative to the origin
private var _velo:Vector2D;	//velocity vector
private var _acc:Vector2D;	//acceleration vector
private var _attractive_coeff:Number = 500;
private var _mass:Number;

Step 10: Ball.as Initiation

As the constructor of Ball class is called, graphics is drawn. Once drawn, the ball will be placed on the stage randomly. We will also set the private variables. All vector quantities will also be initialized at 0, except for the displacement which is measured relative to origin.

public function Ball(radius:Number = 20, color:uint = 0x0000FF)
{
	this.draw(radius, color);
	this._mass = radius / 2; 			//assuming mass is half of radius
	this.x = Math2.randomiseBetween(0, 550);
	this.y = Math2.randomiseBetween(0, 400);
	this._disp = new Vector2D(this.x, this.y);	//set initial displacement
	this._velo = new Vector2D(0, 0);
	this._acc = new Vector2D(0, 0);
}

Step 11: Ball.as Calculate Attractive Force

We need to calculate the underlying force that causes our particles to animate. Guess what, it’s the gravitational force. The function below will help in calculating this force. Note that a cap is applied on the acceleration at 5. The horizontal and vertical components of force are derived using trigonometry; the animation above may help in understanding the mathematics of this.

public function get mass():Number
{
	return _mass;
}
private function getForceAttract (m1:Number, m2:Number, vec2Center:Vector2D):Vector2D
{
	/* calculate attractive force based on the following formula:
	* F = K * m1 * m2 / r * r
	*/
	var numerator:Number = this._attractive_coeff * m1 * m2;
	var denominator:Number = vec2Center.getMagnitude() * vec2Center.getMagnitude();
	var forceMagnitude:Number = numerator / denominator;
	var forceDirection:Number = vec2Center.getAngle();

	//setting a cap
	if (forceMagnitude > 0) forceMagnitude = Math.min(forceMagnitude, 5);

	//deriving force component, horizontal, vertical
	var forceX:Number = forceMagnitude * Math.cos(forceDirection);
	var forceY:Number = forceMagnitude * Math.sin(forceDirection);
	var force:Vector2D = new Vector2D(forceX, forceY);
	return force;
}

Step 12: Ball.as Calculate Acceleration

Once force vector has been obtained, we can calculate the resulting acceleration. Remember, F = ma, so a = F/m.

public function getAcc(vecForce:Vector2D):Vector2D
{
	//setting acceleration due to force
	var vecAcc:Vector2D = vecForce.multiply(1 / this._mass);
	return veccAcc;
}

Step 13: Ball.as Calculate Displacement

With acceleration calculated, we can effectively calculate the resulting displacement.

Remember that force calculated is actually based upon the displacement between the center of the balls.

private function getDispTo(ball:Ball):Vector2D
{
	var currentVector:Vector2D = new Vector2D(ball.x, ball.y);
	currentVector.minusVector(this._disp);
	return currentVector;
}
public function attractedTo(ball:Ball) :void
{
	var toCenter:Vector2D = this.getDispTo(ball);
	var currentForceAttract:Vector2D = this.getForceAttract(ball.mass, this._mass, toCenter);
	this._acc = this.getAcc(currentForceAttract);
	this._velo.addVector(this._acc);
	this._disp.addVector(this._velo);
}

Step 14: Ball.as Implement Displacement

Then, we are able to move our ball to its new location, through the function below. Note that displacement calculated is never implemented onto the ball’s current location straightaway. Such design is to allow checking be done: collision detection between balls.

public function setPosition(vecDisp:Vector2D):void
{
	this.x = Math.round(vecDisp.vecX);
	this.y = Math.round(vecDisp.vecY);
}

Remember, the force is based upon distance between centers. Therefore, the balls will penetrate and continue moving due to attractive force being higher when they are closer. We need to reset acceleration and velocity to 0 when the balls touch one another’s edge. However, we need to obtain a means of detecting the collision between two balls.


Step 15: Ball.as Collision Detection

Collision can be easily checked. Separation between any two balls should not be less than the sum of their radii. Here’s the collision detection function:

public function collisionInto (ball:Ball):Boolean
{
	var hit:Boolean = false;
	var minDist:Number = (ball.width + this.width) / 2;

	if (this.getDispTo(ball).getMagnitude() < minDist)
	{
		hit = true;
	}

	return hit;
}

Step 16: Ball.as Calculate Displace to Repel

Calculate displacement to repel so that two overlapping balls are placed side by side without overlapping.

Usually when collision has been detected between two balls, their state is overlapping each other. We need to make sure that they will just sit nicely on the edge and not overlap. How? We can displace one of the balls away from the other, but we need to calculate the right displacement to adjust first. Here’s the displacement calculation:

public function getRepel (ball:Ball): Vector2D
{
	var minDist:Number = (ball.width + this.width) / 2;
	//calculate distance to repel
	var toBall:Vector2D = this.getDispTo(ball);
	var directToBall:Vector2D = toBall.getVectorDirection();
	directToBall.multiply(minDist);
	directToBall.minusVector(toBall);
	directToBall.multiply( -1);
	return directToBall;
}

Step 17: Ball.as Implement Displacement to Repel

Implementing repelling displacement onto a ball

After we have calculated the right displacement, we need to implement it. The action is like repelling one of the balls. In addition, we need to do another two extra commands. Remember, we are dealing with a dynamic environment. Even after we have set the displacement one of the ball to the edge, acceleration due to force and the resulting velocity will animate it, causing an undesirable movement of jerking in and out. We need to reset these values of acceleration and velocity to zero.

public function repelledBy(ball:Ball):void
{
	this._acc.reset();
	this._velo.reset();
	var repelDisp:Vector2D = getRepel(ball);
	this._disp.addVector(repelDisp);
}

Step 18: Ball.as Animate

Finally, we can animate (render) our ball as if it were being attracted by another. When collision is detected, displacement will be adjusted so that it will not penetrate the edge. This will happen first for the balls when they collide with center, and then for the balls when they collide with one another.

public function animate(center:Ball, all:Array):void
{
	this.attractedTo(center);
	if (collisionInto(center)) this.repelledBy(center);
	for (var i:int = 0; i < all.length; i++)
	{
		var current_ball:Ball = all[i] as Ball;
		if (collisionInto(current_ball) &amp;&amp; current_ball.name != this.name) this.repelledBy(current_ball);
	}
	this.setPosition(this._disp);
}

Step 19: Main.as Private Variables

Moving on to our last class, Main. Main class is generated at the start of the project. Private variables will include the one ball that attracts all the others and the number of balls in our Flash presentation.

private var mainBall:Ball;
private var totalBalls:int = 10;

Step 20: Main.as Draw Balls

First of all, we should initialize balls. There will be one main ball that attract all the others. The others are named so that referencing can be easily done later.

private function createBalls ():void
{
	mainBall = new Ball(50, 0x00FF00);
	this.addChild(mainBall);
	for (var i:int = 0; i < this.totalBalls; i++)
	{
		var currentBall:Ball = new Ball();
		currentBall.name = "ball" + i;
		this.addChild(currentBall);
	}
}

Step 21: Main.as Implement Ball Interaction

Then, assign events to the main ball to make it draggable when clicked and stop when released.

private function init(e:Event = null):void
{
	removeEventListener(Event.ADDED_TO_STAGE, init);
	// entry point
	createBalls();
	mainBall.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
	stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
	animateAll();
}
private function onMouseUp(e:MouseEvent):void
{
	stopDrag();
}
private function onMouseDown(e:MouseEvent):void
{
	e.target.startDrag();
}

Step 22: Main.as Animate Balls

Animating balls that are being attracted by the main. An EnterFrame event is assigned to each ball.

private function animateAll():void
{
	for (var i:uint = 0; i < totalBalls; i++)
	{
		//each ball is pulled by main_ball
		var current_ball:Ball = this.getChildByName("ball" + i) as Ball;
		current_ball.addEventListener(Event.ENTER_FRAME, enterFrame);
	}
}
private function enterFrame(e:Event):void
{
	var allObj:Array = new Array();
	for (var i:int = 0; i <= totalBalls; i++)
	{
		var current_ball:Ball = this.getChildAt(i) as Ball;
		allObj.push(current_ball);
	}
	e.target.animate(mainBall, allObj);
}

Step 23: Test Movie

Finally, press Ctrl + Enter to preview the animation.


Conclusion

To bring this tutorial one step further, readers may extend this project by implementing other linear forces.

In any case, simulations serve as a great tool in delivering ideas difficult to explain by plain text and image in a Physics classroom environment, especially when the state changes over time.

I hope this little tutorial helps you in some way. Terima kasih (that is “thank you” in Malaysia) for taking time to read and looking forward to hearing comments from fellow readers.



View full post on Activetuts+

Jun 27, 2011 Posted on Jun 27, 2011 in Hints and Tips | 0 comments

Say Hello to the All-New Wptuts+ (And Win WordPress Goodies)!

I’m incredibly excited to let you know about the latest addition to the ever-expanding Tuts+ network — Wptuts+! Focusing on everything WordPress, the site will be bringing you top-notch tutorials on developing WordPress themes, plugins and widgets, scaling your site, the business of selling WordPress themes, and general advice on how to become an expert at using the platform!

Whether you’ve always wanted to learn more about WordPress (but never known where to start), or are a seasoned expert looking for advanced tips and tricks, Wptuts+ has you covered. Read on to find out more, meet our expert editor, and hear about how to win $1,000+ of WordPress goodies!


WordPress Tutorials, Tips and Advice

WordPress Tutorials, Tips and Advice

Wptuts+ will provide the amazing quality of tutorials you’ve come to expect from Tuts+, focused toward teaching you everything you need to become a WordPress expert. We have some fantastic content in the works, and you can subscribe in the following ways to ensure you don’t miss out!

  • Subscribe to the RSS Feed
  • Follow @envatowp on Twitter
  • Like Wptuts+ on Facebook

After working as the editor of Webdesigntuts+ for the past few months, your editor — Brandon Jones — will be moving over to share his incredible wealth of WordPress knowledge on Wptuts+!

Brandon Jones is currently the third highest-selling author on ThemeForest, Envato’s marketplace for buying and selling website themes. He couldn’t be more qualified to head up Wptuts+, and I hope you’re looking forward to receiving tips from one of the most successful WordPress developers we’ve ever had the pleasure of working with.


$1,200 of Prizes and Goodies Up For Grabs!

To celebrate the launch of our latest Tuts+ site, we’ve organised a fantastic giveaway with some brilliant prizes for anyone who loves WordPress! With a total value of over $1,200, it’s a fantastic collection of resources and subscriptions. Check out the full details, and take part in the contest!

Finally, if you have any feedback or ideas for Wptuts+, we’d love to hear them. Head over to the site and let us know what you’d like to see!



View full post on Activetuts+

Jun 24, 2011 Posted on Jun 24, 2011 in Hints and Tips | 10 comments

Create an Apple Inspired Flash Preloader

Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This tutorial was first published in July, 2009.

Preloaders are a must have in your Flash applications. They tell the user that the program is running but can’t show any contents until they’re sufficiently loaded. In this tutorial I’ll help you create an Apple inspired preloader MovieClip and teach you how to display some loading information. All this using Flash and ActionScript 3.0.


Final Result Preview

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


Step 1: Brief Overview

We’re going to create a preloader MovieClip using Flash tools such as the Rectangle Primitive Tool and something very important to get the correct alignment: the Snap To Objects option. The clip will have its movement in the timeline and we’ll build the code in two classes. The first class will take care of the preloader and the other will be the Document Class, where we’ll start the preloader.


Step 2: Starting

Open Flash and create a new Flash File (ActionScript 3).

Set the stage size to your desired dimensions and add a background color. I’ve used 600 x 300px in size and added a gray radial gradient (#666666, #333333).

””

Step 3: Creating the Basic Shape

This preloader is composed of one simple shape which is repeated 12 times.

Select the Rectangle Primitive Tool and set the corner radius to 15, make sure to lock the corner radius control so every corner is equally rounded.

Set the color to white and and draw a 25 x 85px rectangle, don’t use a stroke.

That’s it, this is the basic shape that will be the main part of our preloader.


Step 4: Positioning the Shapes

Use the Align panel to set the previously created shape in the top-center of the stage.

Duplicate the shape (Cmd + D) and align it to bottom-center.

Duplicate both shapes and then go to Modify > Transform > Rotate 90º.

Here comes the tricky part, select the Free Transform Tool and make sure you’ve selected the Snap To Objects option (this is the magnet icon in the toolbar or you can go to View > Snapping > Snap to Objects). Start rotating the top and bottom shapes, you’ll notice that the rotation stops at every determined angle, we’ll use two stops to separate the shapes from each other, ending into something like this:


Step 5: Changing the Alpha

We’ll change the shapes’ alpha property to get the “follow” effect we’re after. There are 12 shapes, that’s a little more than 8 but to avoid the use of decimals we’ll set 9 in 8 multiples and the for last 3 we’ll add 10. This gives us alpha values of 8, 16, 24…72, 80, 90, 100. Take a look at the image to get the idea.


Step 6: Animating

Convert all the shapes into a single MovieClip and name it “Preloader”. Check the Export for Actionscript checkbox and write “classes.Preloader” in the class textfield. Double-click the clip to get access to its Timeline. The animation process is very simple; add a new Keyframe and rotate the shapes until the 100% alpha shape is in position where the 8% alpha shape was. Repeat this until you get the full animation. The frames should be in this order:

Since the animation is timeline based, the speed will depend on the Frames per Second of your movie, mine is 25fps and I’ve used 2 frames per state.


Step 7: Choosing the Size

Our preloader is 300 x 300px in size, normally it wouldn’t be so large, but it’s good to have the option. Choose an appropiate size for your preloader and center it on the stage. I chose 48 x 48px.


Step 8: Loading Information

Create a Dynamic Textfield and give it the instance name “info”. This will display the total KB to load, the amount currently loaded and the percent that it represents. Write some text to get an idea of the size it will use and center it.


Step 9: Creating the Preloader Class

Create a new ActionScript file and start importing the required classes:

package classes
{
	import flash.display.MovieClip;
	import flash.text.TextField;
	import flash.events.Event;
	import flash.events.ProgressEvent;

Step 10: Extending the Class

public class Preloader extends MovieClip
{

Since our preloader is a MovieClip and it’s using a timeline, we’re going to extend this class using the MovieClip class.


Step 11: Variables

We only need to use one variable in this class. This variable will store the instance name of the textfield we’re using to show the loading information.

private var dataTextField:TextField;

Step 12: Start Function

public function start(dataTextField:TextField):void
{
	this.dataTextField = dataTextField; //Sets the dataTextField var to the parameter value

	/* 	The loaderInfo Object is in charge of the loading process, in this code we add
	   	listeners to check the progress and when the movie is fully loaded */

		this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress);
    	this.loaderInfo.addEventListener(Event.COMPLETE, onComplete);

}

Step 13: The Progress Function

private function onProgress(e:ProgressEvent):void
{
	/* Here we use some local variables to make better-reading code */

	var loadedBytes:int = Math.round(e.target.bytesLoaded  / 1024);
	var totalBytes:int = Math.round(e.target.bytesTotal / 1024);
	var percent:int = (e.target.bytesTotal / e.target.bytesLoaded) * 100;

	/* Sets the loading data to the textfield */

	dataTextField.text = String(loadedBytes + " of " + totalBytes + "KB Loaded\n" + percent + "% Complete");
}
        

Step 14: The Complete Function

private function onComplete(e:Event):void
{
	/* Remove listeners */

	this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onProgress);
	this.loaderInfo.removeEventListener(Event.COMPLETE, onComplete);

	//Here you can add a function to do something specific, I just used a trace */

	trace("Loaded!");
}

Step 15: Document Class

Create a new ActionScript file and start writing:

package classes
{
	import flash.display.MovieClip;

	public class Main extends MovieClip
	{
		public function Main():void
		{
			/* Starts the preloader, "preloader" is the instance name of the clip */

			preloader.start(info);
		}
	}
}

This code will be the document class, so go back to the .Fla file and add “classes.Main” to the class textfield in the properties panel.


Conclusion

You can always change the color of the preloader to use it with differents backgrounds, an easy way to do that is to change the Tint value in the properties of the clip, try it!

Thanks for reading, feel free to leave comments and questions.



View full post on Activetuts+

Page 1 of 612345...»Last »
search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • Tuts+ Community Meetup in New York!
  • HTML5 Canvas Optimization: A Practical Example
  • Recreate the Cover Flow Effect Using Flash and AS3
  • Drawing Activetuts+ to a Close
  • Intro to Dart: Creating a Marquee
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character Code Create Creating Critique Custom design Effect Effects Files Flash from Game Guide HTML5 Introduction Macromedia Motion Muzzle part Player Premium Professional Quick Silverlight Simple Text Tool Tutorial Tuts+ Using Video website Workshop
About Our Site:

Hey there and welcome to "Flash Video Training Source", a resource for anybody interested in learning more about Adobe's great tool. We feature educational videos, which will help you master Adobe Flash and help you get to know all of its features. We at "Flash Video Training Source" believe that video training and video... more

Why don't you follow us on Twitter and get the latest video tutorials twitted to your account. Just click on the floating twitter bar to your right!

Go Back In Time
June 2011
M T W T F S S
« May   Jul »
 12345
6789101112
13141516171819
20212223242526
27282930  
Pretty Blank Box
top

Blogroll

  • Development Blog
  • Documentation
  • Plugins
  • Suggest Ideas
  • Support Forum
  • Themes
  • WordPress Planet

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org

Archives

  • July 2012
  • June 2012
  • May 2012
  • April 2012
  • March 2012
  • February 2012
  • January 2012
  • December 2011
  • November 2011
  • October 2011
  • September 2011
  • August 2011
  • July 2011
  • June 2011
  • May 2011
  • April 2011
  • March 2011
  • February 2011
  • January 2011
  • December 2010
  • November 2010
  • October 2010
  • September 2010
  • August 2010
  • July 2010
  • June 2010
  • May 2010
  • April 2010
Powered by WordPress  |  Designed by Elegant Themes  |  Lightning Fast Hosting by Site 5 Hosting