logo
468x60-2-495


  • Home
  • Privacy Policy
  • About
search
top
Sep 15, 2011 Posted on Sep 15, 2011 in Hints and Tips | 10 comments

An Introduction to FlashPunk: The Basics

Learn the basics of how FlashPunk works – an amazing library to save you time and help you create the perfect game!


Final Result Preview

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

Use the arrow keys to move your character (the blue guy). The red/brown guy is an NPC; the shaded red area is a danger zone, and the green box is a button. You’ll learn how to create all this in this tutorial.


Step 1: What Is FlashPunk?

FlashPunk logo

FlashPunk is an ActionScript 3 library created for the development of Flash games. Basically, it does all the hard work for you and lets you focus entirely on developing your game, rather than on the engine behind it. The best part about it is that you don’t need Flash Pro to work with it: you can do everything with a free code editor like FlashDevelop. Not to mention it’s way faster when it comes to drawing things on screen, since it uses blitting!

This tutorial will go through all the basics of FlashPunk. After following it, you’ll be ready to make a simple game with this amazing library!


Step 2: Initializing the Engine

Begin by downloading the latest version of FlashPunk from the official site (this tutorial uses the version from August 30, 2011). Put the “net” folder, with all its contents, in your “src” folder.

FlashPunk has a class called Engine. This class is what starts everything in the library. Think of it as a Main class, but with special code to power up all the classes in FlashPunk. In order to use the Engine class, we will modify the Main class a little bit.

package
{
	import net.flashpunk.Engine;

	[Frame(factoryClass="Preloader")]
	public class Main extends Engine
	{

		public function Main():void
		{

		}

	}

}

Now, our class extends Engine. In Main‘s constructor, we need to make a call to the Engine constructor: this is what sets the important information about the game: width, height, framerate and whether the engine should run at a fixed framerate or not.

public function Main():void
{
	super(550, 400, 30, false);
}

There is a function that can (and must be) overridden from the Engine class: the init() function. It will run only once, and will initialize everything to get the game working.

override public function init():void
{
	trace("The game has started!");
}

I’m pretty sure everyone wants to put something on the screen and see this engine working! Because of that, the next few steps will cover the very basics of the elements of FlashPunk, adding depth as the tutorial goes on.


Step 3: Worlds and Entities

In FlashPunk, there are elements called Worlds and Entities. These are the main elements of the library, and you’ll work with them from the beginning to the very end of your game.

Worlds are pretty much like what is commonly known as a “screen”. Everything in your game will happen in a world: the main menu is a world that will give you access to the actual game world, where you will fight some enemies and die, which will lead you to the game over world, with your scores and statistics about how well you did. More about worlds will be explained later.

Entities are exactly what they seem to be; they live in a world and do something in it: a button is an entity; your character is an entity; enemies and bullets are entities. They are the things that give life to the game.

Given that, we will create the game world (there’s time to make the main menu world later, let’s jump to some action!) by extending FlashPunk’s World class:

package
{
	import net.flashpunk.World;

	public class GameWorld extends World
	{

		public function GameWorld()
		{

		}

	}

}

Now that you have created a world, you need to tell FlashPunk that you want this world to be the active one. Let’s do it in Main.as:

private var _gameWorld:GameWorld;

public function Main():void
{
	super(550, 400, 30, false);

	_gameWorld = new GameWorld();
}

override public function init():void
{
	trace("The game has started!");

	FP.world = _gameWorld;
}

And don’t forget to import net.flashpunk.FP!


Step 4: Adding an Entity, and Giving It an Image

Now that we have our world, we can make an entity by extending the Entity class and adding it to our game world:

package
{
	import net.flashpunk.Entity;

	public class GameEntity extends Entity
	{

		public function GameEntity()
		{

		}

	}

}

And in GameWorld.as:

private var _gameEntity:GameEntity;

public function GameWorld()
{
	_gameEntity = new GameEntity();

	add(_gameEntity);
}

Notice that if you compile and run the game, the entity doesn’t appear in the screen. That’s because it has no image yet! Every entity can have a graphic object. This graphic can be a single image, a spritesheet with animations, tiled images — pretty much anything.

We will add this little image to our entity:

Our Entity

An entity’s graphic can be accessed by the graphic property. That’s how we are going to put the image in it! First, embed it; then, just pass it to Image‘s constructor and FlashPunk will take care of transforming that into something visible for you. Compile and run now. Surprise! Our entity is there!

package
{
	import net.flashpunk.Entity;
	import net.flashpunk.graphics.Image;

	public class GameEntity extends Entity
	{
		[Embed(source = "/../img/EntityImage.png")]
		private const IMAGE:Class;

		public function GameEntity()
		{
			graphic = new Image(IMAGE);
		}

	}

}

This is what you should get:

The entity on the screen

Step 5: Making the Entity Move

Now that we have our entity on the screen, what about making it move? Each Entity has a function called update(), which you must override to use. This function is called by every world in the beginning of each frame. If you need to make your entity move, that’s the place where you put your code!

override public function update():void
{
	x += 10 * FP.elapsed;
	y += 5 * FP.elapsed;
}

And don’t forget to import:

import net.flashpunk.FP;

See it in action! (Refresh the page if you can’t see anything here.)

You may have noticed the use of FP.elapsed. FP.elapsed gives the amount of time that elapsed since the last frame (in seconds), making it very easy to create time-based motion. However, for that to work, you must have set the fourth parameter to the Engine‘s constructor to false. Remember that (Step 2)? Setting it to false means that you want FlashPunk to run with a variable timestep, whereas setting it to true makes FlashPunk run on a fixed timestep. Doing the latter, you don’t need to use FP.elapsed. You will know that every time the update() function is called, a frame has passed.


Step 6: Move the Entity as You Wish With Keyboard Input

We’ve got the entity moving on just one direction in the last step. Introducing keyboard input: now you will be able to move the entity to where you want!

FlashPunk has a class called Input which takes care of both keyboard and mouse input. In this tutorial, we will only use keyboard input for movement. It is very easy:

override public function update():void
{
	if (Input.check(Key.A) || Input.check(Key.LEFT))
	{
		x -= 50 * FP.elapsed;
	}
	else if (Input.check(Key.D) || Input.check(Key.RIGHT))
	{
		x += 50 * FP.elapsed;
	}

	if (Input.check(Key.W) || Input.check(Key.UP))
	{
		y -= 50 * FP.elapsed;
	}
	else if (Input.check(Key.S) || Input.check(Key.DOWN))
	{
		y += 50 * FP.elapsed;
	}
}

And the import statements:

import net.flashpunk.utils.Input;
import net.flashpunk.utils.Key;

Input.check() returns true if the Key passed as an argument is being pressed at the time the function has been called. There are other very useful functions, like Input.pressed(), which returns true if the key has been pressed at the time the function has been called (i.e. the key was up a frame ago and is now down), or Input.released(), which does exactly the opposite.

Another interesting thing that the Input class allows us to do is to define many keys under a single name. For example, we could define Key.UP, Key.W and Key.I as "UP", and only check for Input.check("UP"). That way, we can improve our function:

public function GameEntity()
{
	graphic = new Image(IMAGE);

	Input.define("UP", Key.W, Key.UP);
	Input.define("DOWN", Key.S, Key.DOWN);
	Input.define("LEFT", Key.A, Key.LEFT);
	Input.define("RIGHT", Key.D, Key.RIGHT);
}

override public function update():void
{
	if (Input.check("LEFT"))
	{
		x -= 50 * FP.elapsed;
	}
	else if (Input.check("RIGHT"))
	{
		x += 50 * FP.elapsed;
	}

	if (Input.check("UP"))
	{
		y -= 50 * FP.elapsed;
	}
	else if (Input.check("DOWN"))
	{
		y += 50 * FP.elapsed;
	}
}

And this is what you should get:


Step 7: More About Entities

Entities can do a lot more than just move around and have images. Let’s take a look at what surprises they can hold!

Entities have a property called type. You can set this property to any string you want. This allows you to organize your entities into groups, which will prove very useful in the next step (about worlds). We can, for example, set our entity’s type to “GameEntity”:

public function GameEntity()
{
	graphic = new Image(IMAGE);

	Input.define("UP", Key.W, Key.UP);
	Input.define("DOWN", Key.S, Key.DOWN);
	Input.define("LEFT", Key.A, Key.LEFT);
	Input.define("RIGHT", Key.D, Key.RIGHT);

	type = "GameEntity";
}

Following on that, we have the useful world property and the added() and removed() functions. The world property allows you to access the world from within the entity’s code once the entity has been added to an world. It is like the stage property in common Flash development; the functions are like the ADDED_TO_STAGE and REMOVED_FROM_STAGE event listeners. Here’s an example of the functions working in GameEntity.as:

override public function added():void
{
	trace("The entity has been added to the world!");

	trace("Entities in the world: " + world.count);
}

override public function removed():void
{
	trace("The entity has been removed from the world!");
}

Step 8: Deeper Look at Worlds

It is time to take a deeper look at worlds and how they work. First of all, FlashPunk can only have one world running at once, but your game can have as many worlds as you wish, as long as only one remains active every time.

Worlds have update() functions just as entities do, but their function is a little different: there is actual code in the World class. That means you’ll have to call super.update() every time you override this function.

Apart from entities, worlds can also have graphics added to them. Graphics are images that don’t need to be updated by you (FlashPunk still creates an entity to add them to the world, so the engine will still send a call to an update() function). You can add them by calling addGraphic().

The most important thing about worlds is that they have several functions to retrieve certain entities: getType(), getClass(), getAll(), getLayer() and getInstance(). That way, you can have the world return an array of all the bullets currently in the game, so that you can perform a check against all of them for collision. Very handy, I must say!

Take a look at the code added to World.as. We will use a second image as well:

Our second entity
[Embed(source = "/../img/EntityImage2.png")]
private const IMAGE:Class;

public function GameWorld()
{
	_gameEntity = new GameEntity();

	add(_gameEntity);

	addGraphic(new Image(IMAGE), 0, 50, 50);
}

override public function update():void
{
	super.update();

	var entityArray:Array = [];

	getType("GameEntity", entityArray);

	for each (var entity:Entity in entityArray)
	{
		entity.x = entity.x > 550 ? 550 : entity.x;
		entity.y = entity.y > 400 ? 400 : entity.y;
	}
}

And don’t forget to import net.flashpunk.graphics.Image!

In this code, the addGraphic() function call adds another graphic similar to _gameEntity‘s graphic – think of it as a NPC! – to the world in the position (50, 50). Lines 23-31 show an example of retrieving only entities of a particular kind: we call getType() to get only entities of the “GameEntity” type (currently only one entity). After that, we iterate through every entity retrieved and prevent them from getting past the right and bottom borders. (So, the entity can move outside the screen, but not far.) Simple, isn’t it?


Step 9: Animations

Time for something more interesting! FlashPunk supports animations of all kinds. All you have to do is, instead of creating an instance of Image, create an instance of Spritemap. This class receives a spritesheet and allows you to map frames and link to animations.

In our entity’s class, embed this spritemap:

Our Entity's Sheet

Then, create an instance of Spritemap and pass the spritesheet as a parameter to the constructor. After that, it’s all about calling the add() and play() functions!

[Embed(source = "/../img/EntitySheet.png")]
private const SHEET:Class;

private var _timeInterval:Number;

public function GameEntity()
{
	graphic = new Spritemap(SHEET, 40, 20, onAnimationEnd);
	Spritemap(graphic).add("Stopped", [0]);
	Spritemap(graphic).add("Blinking", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 24);

	Input.define("UP", Key.W, Key.UP);
	Input.define("DOWN", Key.S, Key.DOWN);
	Input.define("LEFT", Key.A, Key.LEFT);
	Input.define("RIGHT", Key.D, Key.RIGHT);

	type = "GameEntity";

	Spritemap(graphic).play("Blinking");
}

private function onAnimationEnd():void
{
	Spritemap(graphic).play("Stopped");

	_timeInterval = 0;
}

override public function update():void
{
	_timeInterval += FP.elapsed;

	if (_timeInterval >= 3)
	{
		Spritemap(graphic).play("Blinking");
	}

	if (Input.check("LEFT"))
	{
		x -= 50 * FP.elapsed;
	}
	else if (Input.check("RIGHT"))
	{
		x += 50 * FP.elapsed;
	}

	if (Input.check("UP"))
	{
		y -= 50 * FP.elapsed;
	}
	else if (Input.check("DOWN"))
	{
		y += 50 * FP.elapsed;
	}
}

The constructor of Spritemap (line 19) takes four arguments: a source to get a graphic from, the width and height of each frame of the spritesheet and a callback function to call when the animation ends (optional). In GameEntity‘s constructor, we create the Spritemap and define two animations: “Stopped”, which only contains the first frame and runs at 0 fps (stopped!) and “Blinking”, which contains all frames and runs at 24 frames per second.

The rest of the code is there to play the “Blinking” animation every three seconds.

Take a look at our entity blinking:


Step 10: Collision

With everything running well, it’s time to introduce another feature: collision detection. FlashPunk has a great collision detection system: all we need to do is set hitboxes for our entities and ask the world to check for collisions. For that, we will create another entity called Box which will contain the following graphic:

Box image
package
{
	import net.flashpunk.Entity;
	import net.flashpunk.graphics.Image;

	public class Box extends Entity
	{
		[Embed(source = "/../img/BoxImage.png")]
		private const IMAGE:Class;

		public function Box()
		{
			graphic = new Image(IMAGE);

			setHitbox(60, 60);
		}

	}

}

And inside GameWorld.as:

private var _box:Box;

public function GameWorld()
{
	_gameEntity = new GameEntity();
	_box = new Box();

	add(_gameEntity);
	add(_box);

	_box.x = 200;
	_box.y = 150;

	addGraphic(new Image(IMAGE), 0, 50, 50);
}

The setHitbox() function sets a rectangle that will act as a hit box for the entity. The first two parameters are the width and height of the box. The next two parameters (optional) are the origin coordinates (x and y) of the rectangle. Doing the same for GameEntity:

public function GameEntity()
{
	graphic = new Spritemap(SHEET, 40, 20, onAnimationEnd);
	Spritemap(graphic).add("Stopped", [0]);
	Spritemap(graphic).add("Blinking", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 24);

	Input.define("UP", Key.W, Key.UP);
	Input.define("DOWN", Key.S, Key.DOWN);
	Input.define("LEFT", Key.A, Key.LEFT);
	Input.define("RIGHT", Key.D, Key.RIGHT);

	type = "GameEntity";

	Spritemap(graphic).play("Blinking");

	setHitbox(40, 20);
}

Now that we have both our entity and the box set up with hitboxes, we need to check for collisions in the world class:

override public function update():void
{
	super.update();

	var entityArray:Array = [];

	getType("GameEntity", entityArray);

	for each (var entity:Entity in entityArray)
	{
		entity.x = entity.x > 550 ? 550 : entity.x;
		entity.y = entity.y > 400 ? 400 : entity.y;
	}

	if (_gameEntity.collideWith(_box, _gameEntity.x, _gameEntity.y))
	{
		trace("Collision!");
	}
}

The collideWith() function checks collision with the entity passed as an argument, virtually placing the first entity (in this case, _gameEntity) in the position specified by the second and third arguments.

Once a collision is detected, there must be a response to it. We will only change the position of the moving entity:

override public function update():void
{
	super.update();

	var entityArray:Array = [];

	getType("GameEntity", entityArray);

	for each (var entity:Entity in entityArray)
	{
		entity.x = entity.x > 550 ? 550 : entity.x;
		entity.y = entity.y > 400 ? 400 : entity.y;
	}

	if (_gameEntity.collideWith(_box, _gameEntity.x, _gameEntity.y))
	{
		_gameEntity.x = _gameEntity.y = 0;
	}
}

Take a look at the example. Try to move the entity into the box.


Step 11: Creating a Simple Button – Adding an Image

FlashPunk doesn’t have any buttons by default. Almost all games need buttons, so in this step we will create a Button class. First of all, a button has three states (as you may know from common Flash development): “Up”, “Over” and “Down”. This spritesheet illustrates that:

A Button

And now let’s start the class:

package
{
	import net.flashpunk.Entity;
	import net.flashpunk.graphics.Spritemap;

	public class Button extends Entity
	{
		protected var _map:Spritemap;

		public function Button(x:Number = 0, y:Number = 0)
		{
			super(x, y);
		}

		public function setSpritemap(asset:*, frameW:uint, frameH:uint):void
		{
			_map = new Spritemap(asset, frameW, frameH);

			_map.add("Up", [0]);
			_map.add("Over", [1]);
			_map.add("Down", [2]);

			graphic = _map;

			setHitbox(frameW, frameH);
		}

		override public function render():void
		{
			super.render();
		}

	}

}

The setSpritemap() function sets a spritemap for the button and sets “animations” for the button. Always the image must have first the “Up” frame, then the “Over”, followed by the “Down” frame. There’s also a call to setHitbox(). The hitbox will be used to check whether the mouse is or isn’t over the button’s box.


Step 12: Creating a Simple Button: Up/Over/Down Controls, Callback

Now that we have our Button successfully showing an image, it’s time to create up, over and down controls. We will do it by creating two Boolean attributes: “over” and “clicked”. We will also detect whether the mouse is over the button’s hit box or not. Add these functions in Button.as:

protected var _over:Boolean;
protected var _clicked:Boolean;

override public function update():void
{
	if (!world)
	{
		return;
	}

	_over = false;
	_clicked = false;

	if (collidePoint(x - world.camera.x, y - world.camera.y, Input.mouseX, Input.mouseY))
	{
		if (Input.mouseDown)
		{
			mouseDown();
		}
		else
		{
			mouseOver();
		}
	}
}

protected function mouseOver():void
{
	_over = true;
}

protected function mouseDown():void
{
	_clicked = true;
}

override public function render():void
{
	if (_clicked)
	{
		_map.play("Down");
	}
	else if (_over)
	{
		_map.play("Over");
	}
	else
	{
		_map.play("Up");
	}

	super.render();
}

And don’t forget to import net.flashpunk.utils.Input.

Following the logic in update(): first of all, both attributes (_clicked and _over) are set to false. After that, we check if the mouse is over the button. If it isn’t, the attributes will remain false and the button will be in the “Up” state. If the mouse is over, we check whether the mouse button is currently down. If that’s true, the button is in the “Down” state and _clicked is set to true; if it’s false, then the button is in the “Over” state and the _over attribute is set to true. These attributes will define which frame the spritemap should go to.

This button will be useless if you can’t detect when the user has effectively clicked it. Let’s change the class a bit in order to support callback functions:

protected var _callback:Function;
protected var _argument:*;

public function Button(callback:Function, argument:*, x:Number = 0, y:Number = 0)
{
	super(x, y);

	_callback = callback;
	_argument = argument;
}

override public function update():void
{
	if (!world)
	{
		return;
	}

	_over = false;
	_clicked = false;

	if (collidePoint(x - world.camera.x, y - world.camera.y, Input.mouseX, Input.mouseY))
	{
		if (Input.mouseReleased)
		{
			clicked();
		}
		else if (Input.mouseDown)
		{
			mouseDown();
		}
		else
		{
			mouseOver();
		}
	}
}

protected function clicked():void
{
	if (!_argument)
	{
		_callback();
	}
	else
	{
		_callback(_argument);
	}
}

Our button is done! This code will allow you to pass a callback function (and optionally an argument) to your button, so whenever the user clicks the button, the function will be called.


Step 13: Creating a Simple Button: Adding It to the Screen

Many steps and nothing on the screen… Time to put a button in there! It’s as simple as adding this code in GameWorld.as:

[Embed(source = "/../img/ButtonSheet.png")]
private const BUTTONSHEET:Class;

private var _button:Button;

public function GameWorld()
{
	_gameEntity = new GameEntity();
	_box = new Box();
	_button = new Button(onButtonClick, null);

	_button.setSpritemap(BUTTONSHEET, 50, 40);

	add(_gameEntity);
	add(_box);
	add(_button);

	_box.x = 200;
	_box.y = 150;

	_button.x = 400;
	_button.y = 200;

	addGraphic(new Image(IMAGE), 0, 50, 50);
}

private function onButtonClick():void
{
	FP.screen.color = Math.random() * 0xFFFFFF;

	trace("The button has been clicked!");
}

Now all you have to do is compile the project and the button will be there!


Step 14: The Console

And now the final feature from FlashPunk that will be presented in this tutorial! The Console is FlashPunk’s tool for debugging: it features logs, which are pretty much like traces; shows the time taken to run important engine step; and displays how many entities are on screen and the current FPS. It’s a great tool to use when developing your game. To enable it, just add the following line to Main.as:

override public function init():void
{
	trace("The game has started!");

	FP.console.enable();

	FP.world = _gameWorld;
}

And to log anything in it, use the FP.log() function. For example, let’s change that trace() call:

override public function init():void
{
	FP.console.enable();

	FP.log("The game has started!");

	FP.world = _gameWorld;
}

That’s pretty much it! You’ll see that the “Output” part from the debugging console now shows the log. You can go ahead and change all the trace() calls in our code to calls to FP.log().


Conclusion

And that’s our introduction to FlashPunk, covering the most important aspects of this amazing library: entities, worlds, images and animations; collision, buttons, input and movement. I hope you’ll like this library as much as I do – it really makes work easier!



View full post on Activetuts+

banner ad

10 Responses to “An Introduction to FlashPunk: The Basics”

  1. Daniel Sidhion says:
    September 15, 2011 at 9:23 pm

    Learn the basics of how FlashPunk works – an amazing library to save you time and help you create the perfect game!


    Final Result Preview

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

    Use the arrow keys to move your character (the blue guy). The red/brown guy is an NPC; the shaded red area is a danger zone, and the green box is a button. You’ll learn how to create all this in this tutorial.


    Step 1: What Is FlashPunk?

    FlashPunk logo

    FlashPunk is an ActionScript 3 library created for the development of Flash games. Basically, it does all the hard work for you and lets you focus entirely on developing your game, rather than on the engine behind it. The best part about it is that you don’t need Flash Pro to work with it: you can do everything with a free code editor like FlashDevelop. Not to mention it’s way faster when it comes to drawing things on screen, since it uses blitting!

    This tutorial will go through all the basics of FlashPunk. After following it, you’ll be ready to make a simple game with this amazing library!


    Step 2: Initializing the Engine

    Begin by downloading the latest version of FlashPunk from the official site (this tutorial uses the version from August 30, 2011). Put the “net” folder, with all its contents, in your “src” folder.

    FlashPunk has a class called Engine. This class is what starts everything in the library. Think of it as a Main class, but with special code to power up all the classes in FlashPunk. In order to use the Engine class, we will modify the Main class a little bit.

    
    
    package
    {
    	import net.flashpunk.Engine;
    
    	[Frame(factoryClass="Preloader")]
    	public class Main extends Engine
    	{
    
    		public function Main():void
    		{
    
    		}
    
    	}
    
    }
    

    Now, our class extends Engine. In Main‘s constructor, we need to make a call to the Engine constructor: this is what sets the important information about the game: width, height, framerate and whether the engine should run at a fixed framerate or not.

    
    
    public function Main():void
    {
    	super(550, 400, 30, false);
    }
    

    There is a function that can (and must be) overridden from the Engine class: the init() function. It will run only once, and will initialize everything to get the game working.

    
    
    override public function init():void
    {
    	trace("The game has started!");
    }
    

    I’m pretty sure everyone wants to put something on the screen and see this engine working! Because of that, the next few steps will cover the very basics of the elements of FlashPunk, adding depth as the tutorial goes on.


    Step 3: Worlds and Entities

    In FlashPunk, there are elements called Worlds and Entities. These are the main elements of the library, and you’ll work with them from the beginning to the very end of your game.

    Worlds are pretty much like what is commonly known as a “screen”. Everything in your game will happen in a world: the main menu is a world that will give you access to the actual game world, where you will fight some enemies and die, which will lead you to the game over world, with your scores and statistics about how well you did. More about worlds will be explained later.

    Entities are exactly what they seem to be; they live in a world and do something in it: a button is an entity; your character is an entity; enemies and bullets are entities. They are the things that give life to the game.

    Given that, we will create the game world (there’s time to make the main menu world later, let’s jump to some action!) by extending FlashPunk’s World class:

    
    
    package
    {
    	import net.flashpunk.World;
    
    	public class GameWorld extends World
    	{
    
    		public function GameWorld()
    		{
    
    		}
    
    	}
    
    }
    

    Now that you have created a world, you need to tell FlashPunk that you want this world to be the active one. Let’s do it in Main.as:

    
    
    private var _gameWorld:GameWorld;
    
    public function Main():void
    {
    	super(550, 400, 30, false);
    
    	_gameWorld = new GameWorld();
    }
    
    override public function init():void
    {
    	trace("The game has started!");
    
    	FP.world = _gameWorld;
    }
    

    And don’t forget to import net.flashpunk.FP!


    Step 4: Adding an Entity, and Giving It an Image

    Now that we have our world, we can make an entity by extending the Entity class and adding it to our game world:

    
    
    package
    {
    	import net.flashpunk.Entity;
    
    	public class GameEntity extends Entity
    	{
    
    		public function GameEntity()
    		{
    
    		}
    
    	}
    
    }
    

    And in GameWorld.as:

    
    
    private var _gameEntity:GameEntity;
    
    public function GameWorld()
    {
    	_gameEntity = new GameEntity();
    
    	add(_gameEntity);
    }
    

    Notice that if you compile and run the game, the entity doesn’t appear in the screen. That’s because it has no image yet! Every entity can have a graphic object. This graphic can be a single image, a spritesheet with animations, tiled images — pretty much anything.

    We will add this little image to our entity:

    Our Entity

    An entity’s graphic can be accessed by the graphic property. That’s how we are going to put the image in it! First, embed it; then, just pass it to Image‘s constructor and FlashPunk will take care of transforming that into something visible for you. Compile and run now. Surprise! Our entity is there!

    
    
    package
    {
    	import net.flashpunk.Entity;
    	import net.flashpunk.graphics.Image;
    
    	public class GameEntity extends Entity
    	{
    		[Embed(source = "/../img/EntityImage.png")]
    		private const IMAGE:Class;
    
    		public function GameEntity()
    		{
    			graphic = new Image(IMAGE);
    		}
    
    	}
    
    }
    

    This is what you should get:

    The entity on the screen

    Step 5: Making the Entity Move

    Now that we have our entity on the screen, what about making it move? Each Entity has a function called update(), which you must override to use. This function is called by every world in the beginning of each frame. If you need to make your entity move, that’s the place where you put your code!

    
    
    override public function update():void
    {
    	x += 10 * FP.elapsed;
    	y += 5 * FP.elapsed;
    }
    

    And don’t forget to import:

    
    
    import net.flashpunk.FP;
    

    See it in action! (Refresh the page if you can’t see anything here.)

    You may have noticed the use of FP.elapsed. FP.elapsed gives the amount of time that elapsed since the last frame (in seconds), making it very easy to create time-based motion. However, for that to work, you must have set the fourth parameter to the Engine‘s constructor to false. Remember that (Step 2)? Setting it to false means that you want FlashPunk to run with a variable timestep, whereas setting it to true makes FlashPunk run on a fixed timestep. Doing the latter, you don’t need to use FP.elapsed. You will know that every time the update() function is called, a frame has passed.


    Step 6: Move the Entity as You Wish With Keyboard Input

    We’ve got the entity moving on just one direction in the last step. Introducing keyboard input: now you will be able to move the entity to where you want!

    FlashPunk has a class called Input which takes care of both keyboard and mouse input. In this tutorial, we will only use keyboard input for movement. It is very easy:

    
    
    override public function update():void
    {
    	if (Input.check(Key.A) || Input.check(Key.LEFT))
    	{
    		x -= 50 * FP.elapsed;
    	}
    	else if (Input.check(Key.D) || Input.check(Key.RIGHT))
    	{
    		x += 50 * FP.elapsed;
    	}
    
    	if (Input.check(Key.W) || Input.check(Key.UP))
    	{
    		y -= 50 * FP.elapsed;
    	}
    	else if (Input.check(Key.S) || Input.check(Key.DOWN))
    	{
    		y += 50 * FP.elapsed;
    	}
    }
    

    And the import statements:

    
    
    import net.flashpunk.utils.Input;
    import net.flashpunk.utils.Key;
    

    Input.check() returns true if the Key passed as an argument is being pressed at the time the function has been called. There are other very useful functions, like Input.pressed(), which returns true if the key has been pressed at the time the function has been called (i.e. the key was up a frame ago and is now down), or Input.released(), which does exactly the opposite.

    Another interesting thing that the Input class allows us to do is to define many keys under a single name. For example, we could define Key.UP, Key.W and Key.I as "UP", and only check for Input.check("UP"). That way, we can improve our function:

    
    
    public function GameEntity()
    {
    	graphic = new Image(IMAGE);
    
    	Input.define("UP", Key.W, Key.UP);
    	Input.define("DOWN", Key.S, Key.DOWN);
    	Input.define("LEFT", Key.A, Key.LEFT);
    	Input.define("RIGHT", Key.D, Key.RIGHT);
    }
    
    override public function update():void
    {
    	if (Input.check("LEFT"))
    	{
    		x -= 50 * FP.elapsed;
    	}
    	else if (Input.check("RIGHT"))
    	{
    		x += 50 * FP.elapsed;
    	}
    
    	if (Input.check("UP"))
    	{
    		y -= 50 * FP.elapsed;
    	}
    	else if (Input.check("DOWN"))
    	{
    		y += 50 * FP.elapsed;
    	}
    }
    

    And this is what you should get:


    Step 7: More About Entities

    Entities can do a lot more than just move around and have images. Let’s take a look at what surprises they can hold!

    Entities have a property called type. You can set this property to any string you want. This allows you to organize your entities into groups, which will prove very useful in the next step (about worlds). We can, for example, set our entity’s type to “GameEntity”:

    
    
    public function GameEntity()
    {
    	graphic = new Image(IMAGE);
    
    	Input.define("UP", Key.W, Key.UP);
    	Input.define("DOWN", Key.S, Key.DOWN);
    	Input.define("LEFT", Key.A, Key.LEFT);
    	Input.define("RIGHT", Key.D, Key.RIGHT);
    
    	type = "GameEntity";
    }
    

    Following on that, we have the useful world property and the added() and removed() functions. The world property allows you to access the world from within the entity’s code once the entity has been added to an world. It is like the stage property in common Flash development; the functions are like the ADDED_TO_STAGE and REMOVED_FROM_STAGE event listeners. Here’s an example of the functions working in GameEntity.as:

    
    
    override public function added():void
    {
    	trace("The entity has been added to the world!");
    
    	trace("Entities in the world: " + world.count);
    }
    
    override public function removed():void
    {
    	trace("The entity has been removed from the world!");
    }
    

    Step 8: Deeper Look at Worlds

    It is time to take a deeper look at worlds and how they work. First of all, FlashPunk can only have one world running at once, but your game can have as many worlds as you wish, as long as only one remains active every time.

    Worlds have update() functions just as entities do, but their function is a little different: there is actual code in the World class. That means you’ll have to call super.update() every time you override this function.

    Apart from entities, worlds can also have graphics added to them. Graphics are images that don’t need to be updated by you (FlashPunk still creates an entity to add them to the world, so the engine will still send a call to an update() function). You can add them by calling addGraphic().

    The most important thing about worlds is that they have several functions to retrieve certain entities: getType(), getClass(), getAll(), getLayer() and getInstance(). That way, you can have the world return an array of all the bullets currently in the game, so that you can perform a check against all of them for collision. Very handy, I must say!

    Take a look at the code added to World.as. We will use a second image as well:

    Our second entity
    
    
    [Embed(source = "/../img/EntityImage2.png")]
    private const IMAGE:Class;
    
    public function GameWorld()
    {
    	_gameEntity = new GameEntity();
    
    	add(_gameEntity);
    
    	addGraphic(new Image(IMAGE), 0, 50, 50);
    }
    
    override public function update():void
    {
    	super.update();
    
    	var entityArray:Array = [];
    
    	getType("GameEntity", entityArray);
    
    	for each (var entity:Entity in entityArray)
    	{
    		entity.x = entity.x > 550 ? 550 : entity.x;
    		entity.y = entity.y > 400 ? 400 : entity.y;
    	}
    }
    

    And don’t forget to import net.flashpunk.graphics.Image!

    In this code, the addGraphic() function call adds another graphic similar to _gameEntity‘s graphic – think of it as a NPC! – to the world in the position (50, 50). Lines 23-31 show an example of retrieving only entities of a particular kind: we call getType() to get only entities of the “GameEntity” type (currently only one entity). After that, we iterate through every entity retrieved and prevent them from getting past the right and bottom borders. (So, the entity can move outside the screen, but not far.) Simple, isn’t it?


    Step 9: Animations

    Time for something more interesting! FlashPunk supports animations of all kinds. All you have to do is, instead of creating an instance of Image, create an instance of Spritemap. This class receives a spritesheet and allows you to map frames and link to animations.

    In our entity’s class, embed this spritemap:

    Our Entity's Sheet

    Then, create an instance of Spritemap and pass the spritesheet as a parameter to the constructor. After that, it’s all about calling the add() and play() functions!

    
    
    [Embed(source = "/../img/EntitySheet.png")]
    private const SHEET:Class;
    
    private var _timeInterval:Number;
    
    public function GameEntity()
    {
    	graphic = new Spritemap(SHEET, 40, 20, onAnimationEnd);
    	Spritemap(graphic).add("Stopped", [0]);
    	Spritemap(graphic).add("Blinking", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 24);
    
    	Input.define("UP", Key.W, Key.UP);
    	Input.define("DOWN", Key.S, Key.DOWN);
    	Input.define("LEFT", Key.A, Key.LEFT);
    	Input.define("RIGHT", Key.D, Key.RIGHT);
    
    	type = "GameEntity";
    
    	Spritemap(graphic).play("Blinking");
    }
    
    private function onAnimationEnd():void
    {
    	Spritemap(graphic).play("Stopped");
    
    	_timeInterval = 0;
    }
    
    override public function update():void
    {
    	_timeInterval += FP.elapsed;
    
    	if (_timeInterval >= 3)
    	{
    		Spritemap(graphic).play("Blinking");
    	}
    
    	if (Input.check("LEFT"))
    	{
    		x -= 50 * FP.elapsed;
    	}
    	else if (Input.check("RIGHT"))
    	{
    		x += 50 * FP.elapsed;
    	}
    
    	if (Input.check("UP"))
    	{
    		y -= 50 * FP.elapsed;
    	}
    	else if (Input.check("DOWN"))
    	{
    		y += 50 * FP.elapsed;
    	}
    }
    

    The constructor of Spritemap (line 19) takes four arguments: a source to get a graphic from, the width and height of each frame of the spritesheet and a callback function to call when the animation ends (optional). In GameEntity‘s constructor, we create the Spritemap and define two animations: “Stopped”, which only contains the first frame and runs at 0 fps (stopped!) and “Blinking”, which contains all frames and runs at 24 frames per second.

    The rest of the code is there to play the “Blinking” animation every three seconds.

    Take a look at our entity blinking:


    Step 10: Collision

    With everything running well, it’s time to introduce another feature: collision detection. FlashPunk has a great collision detection system: all we need to do is set hitboxes for our entities and ask the world to check for collisions. For that, we will create another entity called Box which will contain the following graphic:

    Box image
    
    
    package
    {
    	import net.flashpunk.Entity;
    	import net.flashpunk.graphics.Image;
    
    	public class Box extends Entity
    	{
    		[Embed(source = "/../img/BoxImage.png")]
    		private const IMAGE:Class;
    
    		public function Box()
    		{
    			graphic = new Image(IMAGE);
    
    			setHitbox(60, 60);
    		}
    
    	}
    
    }
    

    And inside GameWorld.as:

    
    
    private var _box:Box;
    
    public function GameWorld()
    {
    	_gameEntity = new GameEntity();
    	_box = new Box();
    
    	add(_gameEntity);
    	add(_box);
    
    	_box.x = 200;
    	_box.y = 150;
    
    	addGraphic(new Image(IMAGE), 0, 50, 50);
    }
    

    The setHitbox() function sets a rectangle that will act as a hit box for the entity. The first two parameters are the width and height of the box. The next two parameters (optional) are the origin coordinates (x and y) of the rectangle. Doing the same for GameEntity:

    
    
    public function GameEntity()
    {
    	graphic = new Spritemap(SHEET, 40, 20, onAnimationEnd);
    	Spritemap(graphic).add("Stopped", [0]);
    	Spritemap(graphic).add("Blinking", [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 24);
    
    	Input.define("UP", Key.W, Key.UP);
    	Input.define("DOWN", Key.S, Key.DOWN);
    	Input.define("LEFT", Key.A, Key.LEFT);
    	Input.define("RIGHT", Key.D, Key.RIGHT);
    
    	type = "GameEntity";
    
    	Spritemap(graphic).play("Blinking");
    
    	setHitbox(40, 20);
    }
    

    Now that we have both our entity and the box set up with hitboxes, we need to check for collisions in the world class:

    
    
    override public function update():void
    {
    	super.update();
    
    	var entityArray:Array = [];
    
    	getType("GameEntity", entityArray);
    
    	for each (var entity:Entity in entityArray)
    	{
    		entity.x = entity.x > 550 ? 550 : entity.x;
    		entity.y = entity.y > 400 ? 400 : entity.y;
    	}
    
    	if (_gameEntity.collideWith(_box, _gameEntity.x, _gameEntity.y))
    	{
    		trace("Collision!");
    	}
    }
    

    The collideWith() function checks collision with the entity passed as an argument, virtually placing the first entity (in this case, _gameEntity) in the position specified by the second and third arguments.

    Once a collision is detected, there must be a response to it. We will only change the position of the moving entity:

    
    
    override public function update():void
    {
    	super.update();
    
    	var entityArray:Array = [];
    
    	getType("GameEntity", entityArray);
    
    	for each (var entity:Entity in entityArray)
    	{
    		entity.x = entity.x > 550 ? 550 : entity.x;
    		entity.y = entity.y > 400 ? 400 : entity.y;
    	}
    
    	if (_gameEntity.collideWith(_box, _gameEntity.x, _gameEntity.y))
    	{
    		_gameEntity.x = _gameEntity.y = 0;
    	}
    }
    

    Take a look at the example. Try to move the entity into the box.


    Step 11: Creating a Simple Button – Adding an Image

    FlashPunk doesn’t have any buttons by default. Almost all games need buttons, so in this step we will create a Button class. First of all, a button has three states (as you may know from common Flash development): “Up”, “Over” and “Down”. This spritesheet illustrates that:

    A Button

    And now let’s start the class:

    
    
    package
    {
    	import net.flashpunk.Entity;
    	import net.flashpunk.graphics.Spritemap;
    
    	public class Button extends Entity
    	{
    		protected var _map:Spritemap;
    
    		public function Button(x:Number = 0, y:Number = 0)
    		{
    			super(x, y);
    		}
    
    		public function setSpritemap(asset:*, frameW:uint, frameH:uint):void
    		{
    			_map = new Spritemap(asset, frameW, frameH);
    
    			_map.add("Up", [0]);
    			_map.add("Over", [1]);
    			_map.add("Down", [2]);
    
    			graphic = _map;
    
    			setHitbox(frameW, frameH);
    		}
    
    		override public function render():void
    		{
    			super.render();
    		}
    
    	}
    
    }
    

    The setSpritemap() function sets a spritemap for the button and sets “animations” for the button. Always the image must have first the “Up” frame, then the “Over”, followed by the “Down” frame. There’s also a call to setHitbox(). The hitbox will be used to check whether the mouse is or isn’t over the button’s box.


    Step 12: Creating a Simple Button: Up/Over/Down Controls, Callback

    Now that we have our Button successfully showing an image, it’s time to create up, over and down controls. We will do it by creating two Boolean attributes: “over” and “clicked”. We will also detect whether the mouse is over the button’s hit box or not. Add these functions in Button.as:

    
    
    protected var _over:Boolean;
    protected var _clicked:Boolean;
    
    override public function update():void
    {
    	if (!world)
    	{
    		return;
    	}
    
    	_over = false;
    	_clicked = false;
    
    	if (collidePoint(x - world.camera.x, y - world.camera.y, Input.mouseX, Input.mouseY))
    	{
    		if (Input.mouseDown)
    		{
    			mouseDown();
    		}
    		else
    		{
    			mouseOver();
    		}
    	}
    }
    
    protected function mouseOver():void
    {
    	_over = true;
    }
    
    protected function mouseDown():void
    {
    	_clicked = true;
    }
    
    override public function render():void
    {
    	if (_clicked)
    	{
    		_map.play("Down");
    	}
    	else if (_over)
    	{
    		_map.play("Over");
    	}
    	else
    	{
    		_map.play("Up");
    	}
    
    	super.render();
    }
    

    And don’t forget to import net.flashpunk.utils.Input.

    Following the logic in update(): first of all, both attributes (_clicked and _over) are set to false. After that, we check if the mouse is over the button. If it isn’t, the attributes will remain false and the button will be in the “Up” state. If the mouse is over, we check whether the mouse button is currently down. If that’s true, the button is in the “Down” state and _clicked is set to true; if it’s false, then the button is in the “Over” state and the _over attribute is set to true. These attributes will define which frame the spritemap should go to.

    This button will be useless if you can’t detect when the user has effectively clicked it. Let’s change the class a bit in order to support callback functions:

    
    
    protected var _callback:Function;
    protected var _argument:*;
    
    public function Button(callback:Function, argument:*, x:Number = 0, y:Number = 0)
    {
    	super(x, y);
    
    	_callback = callback;
    	_argument = argument;
    }
    
    override public function update():void
    {
    	if (!world)
    	{
    		return;
    	}
    
    	_over = false;
    	_clicked = false;
    
    	if (collidePoint(x - world.camera.x, y - world.camera.y, Input.mouseX, Input.mouseY))
    	{
    		if (Input.mouseReleased)
    		{
    			clicked();
    		}
    		else if (Input.mouseDown)
    		{
    			mouseDown();
    		}
    		else
    		{
    			mouseOver();
    		}
    	}
    }
    
    protected function clicked():void
    {
    	if (!_argument)
    	{
    		_callback();
    	}
    	else
    	{
    		_callback(_argument);
    	}
    }
    

    Our button is done! This code will allow you to pass a callback function (and optionally an argument) to your button, so whenever the user clicks the button, the function will be called.


    Step 13: Creating a Simple Button: Adding It to the Screen

    Many steps and nothing on the screen… Time to put a button in there! It’s as simple as adding this code in GameWorld.as:

    
    
    [Embed(source = "/../img/ButtonSheet.png")]
    private const BUTTONSHEET:Class;
    
    private var _button:Button;
    
    public function GameWorld()
    {
    	_gameEntity = new GameEntity();
    	_box = new Box();
    	_button = new Button(onButtonClick, null);
    
    	_button.setSpritemap(BUTTONSHEET, 50, 40);
    
    	add(_gameEntity);
    	add(_box);
    	add(_button);
    
    	_box.x = 200;
    	_box.y = 150;
    
    	_button.x = 400;
    	_button.y = 200;
    
    	addGraphic(new Image(IMAGE), 0, 50, 50);
    }
    
    private function onButtonClick():void
    {
    	FP.screen.color = Math.random() * 0xFFFFFF;
    
    	trace("The button has been clicked!");
    }
    

    Now all you have to do is compile the project and the button will be there!


    Step 14: The Console

    And now the final feature from FlashPunk that will be presented in this tutorial! The Console is FlashPunk’s tool for debugging: it features logs, which are pretty much like traces; shows the time taken to run important engine step; and displays how many entities are on screen and the current FPS. It’s a great tool to use when developing your game. To enable it, just add the following line to Main.as:

    
    
    override public function init():void
    {
    	trace("The game has started!");
    
    	FP.console.enable();
    
    	FP.world = _gameWorld;
    }
    

    And to log anything in it, use the FP.log() function. For example, let’s change that trace() call:

    
    
    override public function init():void
    {
    	FP.console.enable();
    
    	FP.log("The game has started!");
    
    	FP.world = _gameWorld;
    }
    

    That’s pretty much it! You’ll see that the “Output” part from the debugging console now shows the log. You can go ahead and change all the trace() calls in our code to calls to FP.log().


    Conclusion

    And that’s our introduction to FlashPunk, covering the most important aspects of this amazing library: entities, worlds, images and animations; collision, buttons, input and movement. I hope you’ll like this library as much as I do – it really makes work easier!


  2. Rahul R Gaikwad says:
    September 15, 2011 at 10:00 pm

    Today we’ll build a fully functional calendar widget using AS3. It’s not rocket science, just an excellent example of using the Date class, which can handle all the complexity of extracting times, dates, months and years. We are also going to use some Flash components, and make sure that this calendar is portable to Flash Builder, FlashDevelop, and so on.


    Final Result Preview

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


    Step 1: Brainstorming

    Before starting to build the code, let’s take a look at what we’ll need:

    • A class file, Calendar.as,
    • A cell grid, to place dates,
    • Labels for day names,
    • Function to get current date, month and year,
    • Function to get previous months’ days,
    • Function to get future months’ days,
    • Something to address the leap year issue,
    • Interface to pick any month and year,
    • Portability (for Flash Builder, FlashDevelop, and other IDEs).

    Step 2: Preparing the Calendar.as Class File

    In this step we shall create a basic structure of our Calendar.as class file.

    There are several ways of creating ActionScript class file, like using FDT, Flash Builder, FlashDevelop. And, of course, the “Higgs Boson” of this multimedia world: the one true Flash IDE. I am using Flash Professional. Create an ActionScript 3.0 class file. The following is the basic structure of Calendar.as to start with.

    
    
    package  {
    
    	import flash.display.Sprite;
    
    	public class Calendar extends Sprite {
    
    		//variables
    
    		public function Calendar () {
    
    			// constructor code
    		}
    	}
    }
    

    I am sure that you have saved this class file as Calendar.as in the new folder for this calendar app. If not please save it.

    Step by step we shall modify this Calendar.as to make it fully functional.

    In the next step we will create a few text fields to label the weekdays and dates.


    Step 3: Setting Up Text Formats for Dates and Weekdays

    In this step we will modify our class by declaring some variables and creating a new function setTextFormat( fontFace, fontSize ).

    We will also passing some parameters to the constructor of the class.

    Initially it will look like “Syntactic Sugar”, but as the tutorial progresses it will become “Syntactic Salt”. Sorry, but we want to keep this class compact so as to make it easily portable. The idea is to have only one class and that’s all.

    So, keep a close watch on the constructor’s number of parameters and their order as we progress.

    Back to modifying the document class…

    
    
    package  {
    
    	import flash.display.Sprite;
    	import flash.text.TextFormat;
    
    	public class Calendar extends Sprite {
    
    		//variables
    		private var dateCellFormat:TextFormat;
    		private var dayLabelTxtFmt:TextFormat;
    
    		public function Calendar( fontFace:String = "Arial", fontSize:int = 15 )
    		{
    			setTextFormat( fontFace, fontSize );
    		}
    
    		private function setTextFormat(whichFont:String, size:int):void	{
    
    			//date text format
    			dateCellFormat = new TextFormat();
    			dateCellFormat.font = whichFont;
    			dateCellFormat.color = 0xFFFFFF;
    			dateCellFormat.size = size;
    			dateCellFormat.align = "center";
    
    			//day label text format
    			dayLabelTxtFmt = new TextFormat();
    			dayLabelTxtFmt.font = "_sans";
    			dayLabelTxtFmt.color = 0x000000;
    			dayLabelTxtFmt.size = size - 3;
    		}
    	}
    }
    

    Observe all the parameters passed to the constructor: we have already assigned values to them. This is the way to create default values for parameters. If no parameters are specified when instantiating the class, these default values will be used instead. We will see this in coming steps.

    Nothing visible yet. Wait for a few steps.


    Step 4: Creating Cell Grid to Arrange Dates

    The calendar is made up of rows and columns forming a grid.

    But how many rows and columns?

    It depends on the calendar type – Vertical or Horizontal.

    Vertical view needs 7 (rows) x 6 (columns), while horizontal view needs 6 (rows) x 7 (columns) as shown:

    Horizontal and Vertical Calendars

    As our calendar is limited to horizontal view for this tutorial, we will need 7 columns and 6 rows. Thus total (7 x 6) = 42 cells.

    So, let us modify our class so that it will generate a grid required for calendar view. Along with adding an import statement, new variables and constructor parameters, we will also add a new function makeDatesCellGrid(..) to the class as shown:

    
    
    package  {
    
    	import flash.display.Sprite;
    	import flash.text.TextFormat;
    	import flash.text.TextField;
    
    	public class Calendar extends Sprite {
    
    		//variables
    		private var cellW:Number; //cell width
    		private var cellP:Number; //cell padding
    		private var allDatesCells:Array = new Array();
    		private var dateCellFormat:TextFormat;
    
    		private var dayLabelTxtFmt:TextFormat;
    
    		public function Calendar( fontFace:String = "Arial", fontSize:int = 15,
    					cellWidth:Number = 30, padding:Number = 3,
    					originX:Number = 15, originY:Number = 15 )
    		{
    			cellW = cellWidth;
    			cellP = padding;
    
    			setTextFormat( fontFace, fontSize );
    
    			makeDatesCellGrid( originX, originY );
    		}
    
    	   private function setTextFormat(whichFont:String, size:int):void {
    
    			//date text format
    			dateCellFormat = new TextFormat();
    			dateCellFormat.font = whichFont;
    			dateCellFormat.color = 0xFFFFFF;
    			dateCellFormat.size = size;
    			dateCellFormat.align = "center";
    
    			//day label text format
    			dayLabelTxtFmt = new TextFormat();
    			dayLabelTxtFmt.font = "_sans";
    			dayLabelTxtFmt.color = 0x000000;
    			dayLabelTxtFmt.size = size - 3;
    		}
    
    		private function makeDatesCellGrid(cellXPos:Number, cellYPos:Number):void {
    
    			//Create grid of date cells
    			for (var i:int = 0; i < 42; i++) {
    
    				var dateCell:TextField = new TextField();
    				addChild(dateCell);
    
    				//position cells to form a grid (7 x 6 = 42)
    				dateCell.x = cellXPos + (cellW * (i-(Math.floor(i/7)*7)));
    				dateCell.y = cellYPos + (cellW * Math.floor(i/7));
    
    				//put all date cells into array for further access
    				allDatesCells.push(dateCell);
    			}
    		}
    	}
    }
    

    Oops, lots of code is written and nothing visible yet. I know you are waiting to see some visible results. For that we will make a temporary change in makeDatesCellGrid by adding a new line as shown:

    
    
    private function makeDatesCellGrid(cellXPos:Number, cellYPos:Number):void
    {
    
    	//Create grid of date cells
    	for (var i:int = 0; i < 42; i++)
    	{
    
    		var dateCell:TextField = new TextField();
    		addChild(dateCell);
    
    		//position cells to form a grid (7 x 6 = 42)
    		dateCell.x = cellXPos + (cellW * (i-(Math.floor(i/7)*7)));
    		dateCell.y = cellYPos + (cellW * Math.floor(i/7));
    
    		//put all date cells into array for further access
    		allDatesCells.push(dateCell);
    
    		allDatesCells[i].text = i;
    	}
    }
    

    Wait…Wait. Now create a new Flash file for ActionScript 3.0 and save this file with any name (ideally Calendar.fla as I did) in the same folder where you saved Calendar.as. Now open the ActionScript panel by pressing “F9″ and type the following code:

    
    
    var myCalendar:Sprite = new Calendar();
    addChild(myCalendar);
    

    Now test the movie.

    DateCellGrid

    There are a few things to fix, like setting up the dates for current month, labels for days, etc.

    Also note that though the constructor can take parameters, we saw a result without passing any values for parameters. This is what I was talking about in the previous step.

    Observe the following two lines we placed inside the constructor,

    
    
    cellW = cellWidth;
    cellP = padding;
    

    We created these vars for global access. We have assigned values to these variables from constructor parameters.

    We used “cellW” for placing cells in grid form. We will use “cellP”, i.e. cell padding (the gap between neighbouring cells), in coming steps. So wait and watch.

    One more thing. After testing above code, remove the line allDatesCells[i].text = i; from the makeDatesCellGrid(..) function. We added it for testing purposes only. Actually, we are going to put dates in those text fields in coming steps.


    Step 5: Adding Names of Weekdays

    In this step we will add labels for weekdays to our calendar. For that we are going to add a new function makeDaysLabels(...) and call it inside the constructor.

    First of all, add new array weekDays[] at the start of the class under the //Variables declaration section. This array hold names of all weekdays as shown:

    
    
    private var weekDays:Array = new Array("Sun","Mon","Tue","Wed","Thu","Fri","Sat");
    

    Now add the following function to the class.

    
    
    private function makeDaysLabels(cellXPos:Number, cellYPos:Number):void {
    
    	//Add week day names
    	for (var i:int = 0; i < 7; i++)	{
    
    		var dayLabel:TextField = new TextField();
    		addChild(dayLabel);
    
    		dayLabel.selectable = false;
    		dayLabel.text = weekDays[i];
    		dayLabel.setTextFormat(dayLabelTxtFmt);
    		dayLabel.x = cellXPos + (cellW * i);
    		dayLabel.y = cellYPos - 15;
    	}
    }
    

    Finally, call this function inside constructor as shown:

    
    
    public function Calendar( fontFace:String = "Arial", fontSize:int = 15,
    						cellWidth:Number = 30, padding:Number = 3,
    						originX:Number = 15, originY:Number = 15 )
    {
    	cellW = cellWidth;
    	cellP = padding;
    
    	setTextFormat( fontFace, fontSize );
    
    	makeDatesCellGrid( originX, originY );
    
    	makeDaysLabels( originX, originY );
    }
    

    Weekdays are ready and waiting for dates to have their right places.


    Step 6: Initializing and Decorating Dates’ Cells

    In this step we will make textfield background visible so that there’s no need to draw a rectangle shape. But if you want to add more style then after completing this tutorial go ahead and create rectangle instances as dates’ cells background and add a gradient color to them. For now it’s ok to set the textfield’s background to true and apply a solid color to it.

    Add the following new function to our class.

    
    
    private function monthSetup():void {
    
    	for (var i:int = 0; i < 42; i++){
    
    		allDatesCells[i].text = "";
    
    		//decor all cells
    		allDatesCells[i].background = true;
    		allDatesCells[i].backgroundColor = 0x000000;
    		allDatesCells[i].border = true;
    		allDatesCells[i].borderColor = 0xCCCCCC;
    		allDatesCells[i].selectable = false;
    		allDatesCells[i].width = allDatesCells[i].height = cellW - cellP;
    		allDatesCells[i].setTextFormat(dateCellFormat);
    	}
    }
    

    Then, call this function inside constructor as shown:

    
    
    public function Calendar( fontFace:String = "Arial", fontSize:int = 15,
    						cellWidth:Number = 30, padding:Number = 3,
    						originX:Number = 15, originY:Number = 15 )
    {
    	cellW = cellWidth;
    	cellP = padding;
    
    	setTextFormat( fontFace, fontSize );
    
    	makeDatesCellGrid( originX, originY );
    
    	makeDaysLabels( originX, originY );
    
     	monthSetup();
    }
    

    Test the movie.

    Dates' Cell background

    Cool… The cells are ready to hold dates for the selected month.


    Step 7: Arrange Dates for Selected Month

    We will add a new function arrangeDates(). This is the most important function for this Calendar app.

    We will be completing the following must-do tasks through this function:

    • Creating date object from Date class.
    • Identifying the column number for first day of selected month.
    • Getting maximum number of days for selected month (with respect to leap year, if applicable).
    • Putting dates at correct places for selected month.
    • Highlighting today’s date, if selected month is current month.

    Pretty challenging tasks, but interesting.

    Ok, back to the job. First we will declare some variables at the start of the class under the //Variables section as shown:

    
    
    private var currDateTime:Date = new Date();
    private var firstDay:Date = new Date(currDateTime.fullYear,currDateTime.month,1);
    private var firstDayColumn:uint = firstDay.day;
    private var daysOfMonths:Array = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
    private var maxDays:uint;
    

    Here currDateTime gives the current time, today’s date, and the current month and year.

    firstDay gives all info about the first day (i.e. Date 1) of the current month. Observe that we have passed the value for third parameter as “1″ for date. Try tracing with various dates to get an idea of what this is doing. But remember to make it “1″ again after testing.

    firstDayColumn, as the name suggests, gives the column number for the first day of current month,

    daysOfMonths array holds maximum number of days from “January…” to “…December”. But for “February” we have “28″ days; in case of leap year we must assign “29″ days as the maximum number of days for February. We will see it later in this step.

    maxDays will hold maximum number of days for current month.

    Fine. Good enough explanation for each var. It’s time for new function arrangeDates().

    In order to understand this function neatly, we will modify it gradually.

    So first, In this function we will get the column number for first day (i.e. Date 1) of a selected month as shown:

    
    
    private function arrangeDates():void {
    
    	//get column number for first day of the month
    	if (firstDay.day == 0)
    	{
    		//when last date of previous month is on saturday then move to second row
    		firstDayColumn = firstDay.day + 7;
    	}
    	else
    	{
    		firstDayColumn = firstDay.day;
    	}
    }
    

    This "firstDayColumn" is important since once we get column number for first day (i.e Date 1) then placing next dates becomes very easy. We will simply use this "firstDayColumn" number inside a for loop to place the next dates. We will see it soon in coming steps.


    Step 8: Getting the Maximum Number of Days for Selected Month

    We will modify the "arrangeDates()" function to get the maximum days for selected month as shown:

    
    
    private function arrangeDates():void {
    
    	//get column number for first day of the month
    	if (firstDay.day == 0)
    	{
    		//when last date of previous month is on saturday then move to second row
    		firstDayColumn = firstDay.day + 7;
    	}
    	else
    	{
    		firstDayColumn = firstDay.day;
    	}
    
    	//get max days for current month w.r.t leap year if any
    	maxDays = (firstDay.getFullYear()%4 == 0 && firstDay.getMonth() == 1 ? 29 : daysOfMonths[firstDay.getMonth()]);
    }
    

    The above new line is a shorthand method for an if statement. New users may consider it “Syntactic Salt”, but once used to it will consider it “Syntactic Sugar”.

    Observe the question mark “?” in the above line. On the left side of this question mark – i.e. "firstDay.getFullYear()%4 == 0 && firstDay.getMonth() == 1" – is a conditional statement. If this left side is true then the statement after the “?” mark (here 29) is executed; if it is false the statment on the right of the “:” mark (here daysOfMonths[firstDay.getMonth()]) is executed. See the image below for a better understanding.

    Short hand method for if statement

    Ok, back to our shorthand if statement. It gives the maximum number of days for selected month. But you have to consider leap years, too. In a leap year, February has 29 maximum days. This leap year comes every fourth year.

    So we have two conditions, one is to check if it is leap year and second is to check if it is February.

    To check whether current year is leap year we used modulus operator (which gives the remainder after dividing one number by another), as in "firstDay.getFullYear() % 4". If it gives a remainder of 0 (zero) then we can say that it is a leap year. For example, 2012 is a leap year, as (2012 % 4 == 0). Similarly (2016 % 4 == 0), so 2016 is a leap year, and so on. If the remainder is nonzero then obviously it is not a leap year. Thus we can detect leap years.

    (Editor’s note: actually, there’s a little more to it than that: years divisible by 100 are usually not leap years – unless they are also divisible by 400. To keep this tutorial simple, we’ll omit that, but you can program it in if you wish!)

    Now we will check whether the current month is “February”. Before that let us consider the index number for months generated by Date class. It starts from 0 for Jan, 1 for Feb, 2 for March and so on. So to find out whether the current month is “February”, we use "firstDay.getMonth() == 1". “1″ for “February”.

    If both these conditions are true then we set maxDays = 29; otherwise we refer to the "daysOfMonths" array.


    Step 9: Placing Dates of Selected Month at Their Positions

    Now we have "maxDays" and "firstDayColumn" with us so we are able to arrange dates for selected month.

    Modify "arrangeDates()" as shown below,

    
    
    private function arrangeDates():void {
    
    	//get column number for first day of the month
    	if (firstDay.day == 0)
    	{
    		//when last date of previous month is on saturday then move to second row
    		firstDayColumn = firstDay.day + 7;
    	}
    	else
    	{
    		firstDayColumn = firstDay.day;
    	}
    
    	//get max days for current month w.r.t leap year if any
    	maxDays = (firstDay.getFullYear()%4 == 0 && firstDay.getMonth() == 1 ? 29 : daysOfMonths[firstDay.getMonth()]);
    
    	//put dates for current month
    	for (var i:int = 0; i < maxDays; i++) {
    
    		allDatesCells[firstDayColumn + i].text = i + 1;
    		allDatesCells[firstDayColumn + i].setTextFormat(dateCellFormat);
    
    		allDatesCells[firstDayColumn + i].alpha = 1;
    	}
    }
    

    We set "allDatesCells[firstDayColumn + i].alpha = 1" for date field as we are going to set previous and next month’s date fields’ alpha to 0.5 in coming steps. So we set alpha = 1 in advance to avoid returning to this function, since this function is almost finished.

    Now "arrangeDates()" function has something to show. But we need to call it somewhere. The function "monthSetup()" is the right place to call this function.

    So modify function "monthSetup()" as shown:

    
    
    private function monthSetup():void {
    
    	for (var i:int = 0; i < 42; i++){
    
    		allDatesCells[i].text = "";
    
    		//decor all cells
    		allDatesCells[i].background = true;
    		allDatesCells[i].backgroundColor = 0x000000;
    		allDatesCells[i].border = true;
    		allDatesCells[i].borderColor = 0xCCCCCC;
    		allDatesCells[i].selectable = false;
    		allDatesCells[i].width = allDatesCells[i].height = cellW - cellP;
    		allDatesCells[i].setTextFormat(dateCellFormat);
    	}
    
    	arrangeDates();
    }
    

    At this point you can test the movie.

    Wow. exciting. See those dates at their positions.

    Dates at their positions

    Step 10: Highlighting Today’s Date

    In this step we will highllight today’s date. So modify the "for" loop in "arrangeDates()" as shown:

    
    
    private function arrangeDates():void {
    
    	//get column number for first day of the month
    	if (firstDay.day == 0)
    	{
    		//when last date of previous month is on saturday then move to second row
    		firstDayColumn = firstDay.day + 7;
    	}
    	else
    	{
    		firstDayColumn = firstDay.day;
    	}
    
    	//get max days for current month w.r.t leap year if any
    	maxDays = (firstDay.getFullYear()%4 == 0 && firstDay.getMonth() == 1 ? 29 : daysOfMonths[firstDay.getMonth()]);
    
    	//put dates for current month
    	for (var i:int = 0; i < maxDays; i++) {
    
    		allDatesCells[firstDayColumn + i].text = i + 1;
    		allDatesCells[firstDayColumn + i].setTextFormat(dateCellFormat);
    
    		allDatesCells[firstDayColumn + i].alpha = 1;
    
    		//Highlight today
    		if (firstDay.fullYear == currDateTime.fullYear && firstDay.month == currDateTime.month)
    		{
    			if(allDatesCells[firstDayColumn + i].text == currDateTime.date)
    			{
    				allDatesCells[firstDayColumn + i].backgroundColor = 0xEE5D15;
    			}
    		}
    	}
    }
    

    Test movie to see today’s date highlighted.

    We are very close to getting that “Calendar” feel. Once the dates of previous month and next month are placed, then we are done – for the current month, at least.


    Step 11: Adding Dates of the Previous Month

    We want to add dates from before the “firstDayColumn”, so we will get all previous date fields in reverse order by using a decrementing "for" loop.

    Add the following new function to the class:

    
    
    private function prevMonthDates():void {
    
    	var prevMonthFirstDay:Date = new Date(firstDay.fullYear,firstDay.month,firstDay.date - 1);
    
    	for (var i:int = firstDayColumn-1; i >= 0; i--) {
    
    		allDatesCells[i].text = prevMonthFirstDay.date - ((firstDayColumn - 1) - i);
    		allDatesCells[i].setTextFormat(dateCellFormat);
    		allDatesCells[i].alpha = 0.5;
    	}
    }
    

    Now call this function inside "monthSetup()" as shown:

    
    
    private function monthSetup():void {
    
    	for (var i:int = 0; i < 42; i++){
    
    		allDatesCells[i].text = "";
    
    		//decor all cells
    		allDatesCells[i].background = true;
    		allDatesCells[i].backgroundColor = 0x000000;
    		allDatesCells[i].border = true;
    		allDatesCells[i].borderColor = 0xCCCCCC;
    		allDatesCells[i].selectable = false;
    		allDatesCells[i].width = allDatesCells[i].height = cellW - cellP;
    		allDatesCells[i].setTextFormat(dateCellFormat);
    	}
    
    	arrangeDates();
    	prevMonthDates();
    }
    

    Test the movie to see the previous month’s dates placed at their positions.


    Step 12: Adding Dates of the Next Month

    In this step we will add dates of next month. Add the following new function to the class as shown:

    
    
    private function nextMonthDates():void {
    
    	for (var i:int = 1; i < (42 - maxDays - (firstDayColumn - 1)); i++){
    
    		allDatesCells[(firstDayColumn - 1) + i + maxDays].text = i;
    		allDatesCells[(firstDayColumn - 1) + i + maxDays].setTextFormat(dateCellFormat);
    		allDatesCells[(firstDayColumn - 1) + i + maxDays].alpha = 0.5;
    	}
    }
    

    Now call this function inside "monthSetup()" function as shown:

    
    
    private function monthSetup():void {
    
    	for (var i:int = 0; i < 42; i++){
    
    		allDatesCells[i].text = "";
    
    		//decor all cells
    		allDatesCells[i].background = true;
    		allDatesCells[i].backgroundColor = 0x000000;
    		allDatesCells[i].border = true;
    		allDatesCells[i].borderColor = 0xCCCCCC;
    		allDatesCells[i].selectable = false;
    		allDatesCells[i].width = allDatesCells[i].height = cellW - cellP;
    		allDatesCells[i].setTextFormat(dateCellFormat);
    	}
    
    	arrangeDates();
    	prevMonthDates();
    	nextMonthDates();
    }
    

    Test the movie to see dates of next month placed at their positions.

    At this point our calendar is ready, displaying all the dates required in the current month’s display. Now in the coming steps we will allow the user to select any month and any year, to complete the Calendar application.


    Step 13: Adding the Capability to Select Any Month

    Selecting any month will add more sense to our Calendar. To select any month from the list, the "ComboBox" component is the best option available.

    Therefore we need to add a ComboBox which holds a list of months. It should be placed at an appropriate position, somewhere near the calendar. So we will allow placing this ComboBox as per the developer’s choice. How will we allow the developer to change this? We will pass parameter for the X and Y positions of this ComboBox to the constructor of Calendar.as.

    To add and place the ComboBox, first consider the following tasks we must perform:

    • Passing parameters for the ComboBox’s "X" and "Y" positions to the constructor.
    • Adding new function "monthPicker(...)" where we will manipulate the ComboBox.
    • Adding one more new function "pickMonth()" which will hear the ComboBox’s events and will call a function to show the selected month.
    • Importing the ComboBox component by dragging it from the Component Panel to the Library Panel of our FLA.

    First, add the following import statements to the class,

    
    
    import flash.events.Event;
    import fl.controls.ComboBox;
    import fl.data.DataProvider;
    

    Then add new variables at start of the class under //Variables section as shown:

    
    
    private var months:Array = [
    								{label:"January", data:0},
    								{label:"February", data:1},
    								{label:"March", data:2},
    								{label:"April", data:3},
    								{label:"May", data:4},
    								{label:"June", data:5},
    								{label:"July", data:6},
    								{label:"August", data:7},
    								{label:"September", data:8},
    								{label:"October", data:9},
    								{label:"November", data:10},
    								{label:"December", data:11},
    							];
    
    private var monthPickerCB:ComboBox; //combobox to pick a month
    

    We will use the "months" array to put values inside combobox.

    Ok, now let us modify the constructor function as shown:

    
    
    public function Calendar( fontFace:String = "Arial", fontSize:int = 15,
    							cellWidth:Number = 30, padding:Number = 3,
    							originX:Number = 15, originY:Number = 15,
    							cbX:Number = 15, cbY:Number = 15 )
    {
    
    		cellW = cellWidth;
    		cellP = padding;
    
    		monthPickerCB = new ComboBox();
    
    		setTextFormat( fontFace, fontSize );
    
    		makeDatesCellGrid( originX, originY );
    
    		makeDaysLabels( originX, originY );
    
    		monthSetup();
    
    		monthPicker( cbX, cbY );
    }
    

    We added the parameters "cbX" and "cbY" into the constructor’s signature to pass position values specified by user, or to use default values if not specified.

    Then we created a ComboBox instance as "monthPickerCB = new ComboBox()".

    We called "monthPicker(...)" in advance, as we are going to create it now.

    So we will add two new functions "monthPicker(...)" and "pickMonth(...)" as shown:

    
    
    private function monthPicker(cbX:Number, cbY:Number):void {
    
    	monthPickerCB.dataProvider = new DataProvider(months);
    	addChild(monthPickerCB);
    
    	//position combobox
    	monthPickerCB.x = cbX;
    	monthPickerCB.y = (cellW * 6) + cbY;
    
    	monthPickerCB.selectedIndex = currDateTime.month;
    
    	monthPickerCB.addEventListener(Event.CHANGE, pickMonth);
    }
    
    private function pickMonth(e:Event):void {
    
    	firstDay.month = ComboBox(e.target).selectedItem.data;
    	monthSetup();
    }
    

    One more step and we are done adding the ComboBox.

    Drag the ComboBox from the Component panel into your Flash file’s Library panel. (Use the Window menu if you can’t find the panels.) This way, we can access the ComboBox component and its classes at runtime.

    Combobox and its prerequisites in the library.

    Test the movie to see combobox at bottom left of the calendar (as default value).

    Now you can display all the months, for the current year.

    Exciting… So we will now add year selection, giving one more dimension to our calendar.


    Step 14: Adding the Capability to Select Any Year

    Selecting any year will add one more dimension to our Calendar. To select any year within a range, the NumericStepper component is a good choice.

    Therefore we will add "NumericStepper" component which will allow the user to increment or decrement the selected year. As with the ComboBox, we will pass parameters to the constructor to specify its X and Y positions.

    To add and place a NumericStepper, we’ll have to perform the following tasks:

    • Passing parameters for NumericStepper’s "X" and "Y" positions to the constructor.
    • Adding new function "yearPicker(...)" where we will manipulate NumericStepper.
    • Adding one more new function "pickYear()" which will hear NumericStepper events and will tell to show the selected year.
    • Importing the NumericStepper component by dragging it from the Component panel to the Library panel of our FLA.

    First, add the following import statement to the class,

    
    
    import fl.controls.NumericStepper;
    

    Then add a new variable at the start of the class under the //Variables section as shown:

    
    
    private var yearPickerNS:NumericStepper; //numeric stepper to pick a year
    

    Ok, now let us modify constructor function as shown:

    
    
    public function Calendar( fontFace:String = "Arial", fontSize:int = 15,
    							cellWidth:Number = 30, padding:Number = 3,
    							originX:Number = 15, originY:Number = 15,
    							cbX:Number = 15, cbY:Number = 15,
    							nsX:Number = 26, nsY:Number = 15,
    							monthsRange:int = 39 )
    {
    
    	cellW = cellWidth;
    	cellP = padding;
    
    	monthPickerCB = new ComboBox();
    
    	yearPickerNS = new NumericStepper();
    
    	setTextFormat( fontFace, fontSize );
    
    	makeDatesCellGrid( originX, originY );
    
    	makeDaysLabels( originX, originY );
    
    	monthSetup();
    
    	monthPicker( cbX, cbY );
    
    	yearPicker( nsX, nsY, monthsRange );
    }
    

    We have added three parameters: "nsX", "nsY" and "monthsRange". The first two are to specify the position, and the third one is to specify the range (previous and next months). 39 will allow to pick any year within the next and previous 40.

    OK, now we will add two new functions "yearPicker(...)" and "pickYear(...)", as shown:

    
    
    private function yearPicker(nsX:Number, nsY:Number, maxYrsRange:int):void {
    
    	yearPickerNS.maximum = currDateTime.fullYear + maxYrsRange;
    	yearPickerNS.minimum = currDateTime.fullYear - maxYrsRange;
    	yearPickerNS.value = currDateTime.fullYear;
    	addChild(yearPickerNS);
    
    	//position numeric stepper
    	yearPickerNS.x = monthPickerCB.width + nsX;
    	yearPickerNS.y = (cellW * 6) + nsY;
    
    	yearPickerNS.addEventListener(Event.CHANGE, pickYear);
    }
    
    private function pickYear(e:Event):void {
    
    	firstDay.fullYear = e.target.value;
    	monthSetup();
    }
    

    One more step and we are done adding the numeric stepper.

    Drag the Numeric Stepper component from the Component panel to your Flash file’s Library panel. This way, we can access the Numeric Stepper component and its classes at runtime.

    That’s it. Test your movie to see a basic Calendar App running.

    Step 15: Customizing the Calendar

    We were testing the Calendar app with default values. Now we will customize it by passing different parameter values to its constructor.

    To start with, we will try using the different fonts available on our system.

    So, in the Flash file, go to the first statement in the ActionScript panel as shown:

    
    
    var myCalendar:Sprite = new Calendar();
    addChild(myCalendar);
    

    Click inside parenthesis next to new Calendar, and type "Courier New". Now your statement will look like this:

    
    
    var myCalendar:Sprite = new Calendar("Courier New");
    

    Test the movie to see the new font applied to dates.

    Now try changing next parameter (font size) like so:

    
    
    var myCalendar:Sprite = new Calendar("Courier New", 17);
    

    While typing the next parameter you will see a code hint pop up, showing all necessary parameters with their default values, like so:

    Code hint for constructor parameter

    Make sure all parameters are there in the code hint popup. There is a bug(?) I have found when I was working on one project, which I’d like to make you aware of.

    When I was writing a document class, at a point when there were only four parameters in the constructor signature, I closed this class file. When I got back to the work, I continued working on this class. At one point there were six parameters. Then I wanted to check this parameter passing stuff. So I opened the Flash file I created for this project and started typing parameters, as we did in our Calendar Flash file. I was expecting my newly added parameters to be displayed in code hints… but surprisingly there were still only four parameters.

    I saved and restarted all related files but the result was the same. After lots of testing I found the reason. The reason was, I created a new folder in the same folder where the document class was placed. I removed this folder outside the main folder, then I opened the class file to make some changes and I saved it. Then I went back to Flash file and started typing parameters and this time all parameters showed up.

    Ok, not a severe bug, but the lesson is: be careful while setting up a folder structure for your project.

    So back to the point where we left off. Try passing proper values for different parameters. You can also set up variables in Flash file (or in a class), so if one value is changed then other related parameters will also get adjusted accordingly – for example, if you want to increase the Font Size then Cell Width must increase accordingly, and so on.


    Step 16: Checking the Portability of This Calendar App

    The real power of this class is that you can use it in any of your project like so:

    • Using in Flash IDE (as we’ve been doing)
    • Calling this Calendar.as inside another document class.
    • Using it with FlashDevelop.
    • Using it with Flash Builder.

    We have already seen how to instantiate Calendar.as in Flash timeline code through this tutorial.

    Now we will see how to call it in another class.

    There is nothing much that we have to do differently when calling our class from another one. We simply put the same code we typed in Flash timeline into some other class. See the "Main.as" class below for better understanding:

    
    
    package
    {
    	import flash.display.Sprite;
    
    	public class Main extends Sprite
    	{
    		public function Main():void
    		{
    			init();
    		}
    
    		private function init():void
    		{
    			var c:Sprite = new Calendar();
    			addChild(c);
    		}
    	}
    }
    

    You can use the above “Main.as” in Flash, FlashDevelop, FlashBuilder, FDT. Only you will have to carry Calendar.as, “Main.as” in your project folders.

    In Flash IDE set this “Main.as” as Document class using Property Inspector panel. Make sure you have both Calendar.as, “Main.as” in your project folder. Also make sure you have “Combobox” and “NumericStepper” in your library panel. Now you can test the movie to see the working calendar.

    FlashDevelop

    Now we will test it with FlashDevelop 4.

    Create a new folder “Calendar_FD”.

    Open FlashDevelop, create a new project, and browse for the above "Calendar_FD" folder. Press OK to create new project.

    FlashDevelop Select Project window

    Inside “Calendar_FD” folder, you will see three new folders: “bin”, “lib” and “src”.

    Now in the “src” folder copy Calendar.as. Also copy above “Main.as” we created and replace it with the auto generated “Main.as” in the same folder.

    Now every thing is set up. But what about the "ComboBox" and "NumericStepper" components? Here no Library panel is present, unlike in the Flash IDE.

    The solution to this issue is making SWC files. We will create a "CalendarComp.swc" file.

    Create a new FLA (in Flash Pro), name it “CalendarComp.fla”, and save it anywhere (but remember its path).

    Drag "ComboBox" and "NumericStepper" components to the Library panel and save the file.

    Open Publish Settings and in the “Flash” tab check “Export SWC” under “SWF settings” group. Hit Publish.

    PublishSettings_SWC

    "CalendarComp.swc" is created in the folder where you saved "CalendarComp.fla", so browse to this folder and copy "CalendarComp.swc" to the "lib" folder of the "Calendar_FD" main folder.

    Back in FlashDevelop, look in the Project Panel. Right click "CalendarComp.swc" and select "Add to Library". Now we can access all class files required for our components, just like in the Flash IDE.

    Add CalendarComp.swc to library.

    Finally click “Test Project” to see your Calendar app running.

    Flash Builder

    How about Flash Builder 4?

    Create a new folder, “Calendar_FB”.

    Open Flash Builder and create a new project.

    Flash Builder Select Project Menu.

    Browse for the above “Calendar_FB” folder. Also enter a project name (I used “MyProject” as a project name). Press Finish to create a new project.

    Flash Builder Select Project window.

    Inside the “Calendar_FB” folder, you will see a “src” directoy, which already contains “MyProject.as” as the main class.

    MyProject Folder structure.

    Copy our Calendar.as class file to this folder. It is now visible in the “Package Explorer”.

    MyProject Folder structure.

    As in, FlashDevelop there is no library panel like the Flash IDE has. So how to get "ComboBox" and "NumericStepper" components?

    The solution is to use a SWC, like we did with FlashDevelop. But you need to specify the class path in Flash Builder.

    So first copy the "CalendarComp.swc" we created in the above section for FlashDevelop, and paste this file inside the “src” folder of the “Calendar_FB” main folder.

    In Flash Builder we need to add a class path. So click on Project > Properties to open the “Properties” window. Select “ActionScript Build Path” and click the “Add SWC…” button. Then browse for “CalendarComp.swc” which you pasted in the “src” folder.

    Project properties.

    Modify “MyProject.as” as shown:

    
    
    package
    {
    	import flash.display.Sprite;
    
    	public class MyProject extends Sprite
    	{
    		public function MyProject():void
    		{
    			var myCalendar:Sprite = new Calendar();
    			addChild(myCalendar);
    		}
    	}
    }
    

    Finally click “Run My Project” to see your Calendar app running.


    Conclusion

    So, friends, I would like to stop at this stage. I hope you have got something useful from this tutorial that will help in your coming projects. Best of luck… See you soon.

    In this tutorial we saw the logical use of the "Date()" class in AS3. We addressed the leap year issue. We displayed the next and previous month’s dates. We saw how to deal with Flash components. We also checked the portability of this Calendar app using FlashDevelop, Flash Builder and Flash Pro. During the process we also saw how to create and use SWC files to access Flash components outside Flash Pro.

    All good. Friends, keep reading Activetuts+. Enjoy!


  3. Michael James Williams says:
    September 15, 2011 at 10:02 pm

    In this Premium Tutorial, you’ll learn to create an entertaining retro game using Flash and ActionScript 3.0. Check out the demo – the result is based on the classic Boxing for the Atari.

    Become a Premium member to follow this awesome tutorial, as well as hundreds of other advanced tutorials and screencasts.


    Preview

    Here’s what you’ll create by the end of this tutorial:

    In the demo above, use the Arrow Keys to move and Z/X to punch.


    Active Premium Membership

    Activetuts+ Premium Membership

    We run a Premium membership system which costs $9 a month (or $22 for 3 months!) which periodically gives members access to extra tutorials, like this one! You’ll also get access to Psd Premium, Vector Premium, Audio Premium, Net Premium, Ae Premium, Cg Premium and Photo Premium too. If you’re a Premium member, you can log in and download the tutorial. If you’re not a member, you can of course join today!

    Also, don’t forget to follow @envatoactive on twitter and grab the Activetuts+ RSS Feed to stay up to date with the latest tutorials and articles.


  4. Michael James Williams says:
    September 15, 2011 at 10:30 pm

    We’ll soon be publishing our first HTML5 tutorials here at Activetuts+, but before we start, here’s a fast and easy tutorial to get up to speed on the basics of HTML – even if you’ve never done any before.


    The Difference Between HTML and .html

    Create a new file, anywhere on your computer, and call it page.html. In Windows, the easiest way to do that is right-click an empty spot within a folder, click New > Text File, then make sure you delete the “.txt” at the end of a file. Windows will probably tell you that it’s dangerous to change the file extension like this; just click OK. Alternatively, you can open a text editor (like Notepad or TextEdit), click File > New, and enter page.html as the filename.

    Once you’ve created the file, open it in a text editor; there are plenty of fancy editors that offer all sorts of HTML-friendly features, but for this tutorial, the aforementioned Notepad or TextEdit will do just fine. (If you just double-click the file, it’ll probably open in your browser, so you’ll either need to open the text editor first and use File > Open to select the file, or (in Windows) right-click the file and choose Open With > Notepad.) Make sure you use a simple text editor rather than a word processor.

    Enter this in your file:

    
    
    Is this HTML?
    

    Save it, and open it in your browser – or just click here to open mine. It’ll look something like this:

    HTML beginner tutorial guide

    So there you go! You’ve created a web page – a .html page – and it displays just fine, with no error messages. That’s it, end of the tutorial, thanks for reading.

    Just kidding, of course.

    Browsers Aren’t Psychic

    Here’s an experiment: take an image file, copy it (so that you don’t damage the original image), and rename the copy to something.html. Then, try to open this with your browser. Click here to open the screenshot above, after it’s been renamed from .png to .html, in your browser.

    Yikes. That’s a lot of gobbledegook. But if you open the original .png file in your browser, it’ll load just fine. Your browser can obviously cope with these files, so what gives?

    When you open a .html file with your browser, it says, “Hey, I know how to deal with .html files!” – it assumes that the contents of the file are written using HyperText Markup Language (HTML for short, as you’ll have guessed), and tries to use everything it knows about this markup language to display the page. Image files aren’t written using HTML, so when it tries to display something that makes any sense using its HTML rules, it fails miserably.

    There are other file extensions that browsers automatically associate with HTML – like .htm – and browsers can also be told to assume that other types of files will contain HTML – like ones ending in .php or .aspx.

    So, not every file that’s written in HTML will end in .html. But does this mean that Is this HTML? is perfect HTML in itself? Well… not exactly.

    People Make Mistakes

    While the actual contents of an image file are usually generated by a program like Paint or Photoshop based on a user’s input, the contents of a .html file may be typed directly into the file by the user. And users, being human, make mistakes.

    Browsers, in general, err on the side of forgiveness; rather than pettily refusing to display a page if the user has made even a simple mistake – like certain overzealous English teachers – it’ll try to guess what the user meant and display the page to the best of its abilities.

    Is this HTML?, you will be shocked to hear, is not ideal HTML, in that it does not contain all of the information a browser would like to see – but it’ll be displayed anyway.

    This means, then, that files containing HTML don’t always end in .html, and files ending in .html don’t always contain perfect HTML. To confuse the issue even further, sometimes you won’t even save a file at all, but rather type HTML straight into a big text box, the contents of which a computer will later insert in the middle of a bigger HTML file, like I’m doing now:

    HTML beginner tutorial guide

    What Makes a “Proper” HTML Page?

    All right, so a single line of English doesn’t count as by-the-book HTML, that’s no surprise. What should we add to our simple file, then?

    Tags

    Tags are the most important element of HTML. A bit like how blog post tags identify the topics of articles, or hashtags identify which hilarious meme a Tweet is joining in on, HTML tags identify something about whatever it is they’re tagging. This is vague, I know, but you’ll see why.

    For example, in our current page:

    
    
    Is this HTML?
    

    …what is “Is this HTML?”. It’s text, sure. Specifically, we could say it’s a paragraph of text. And in order to show this, we can tag the paragraph by wrapping it in <p> tags (p for paragraph – and no, before you ask, there’s no “sentence” tag):

    
    
    <p>Is this HTML?</p>
    

    Each tag starts with an opening chevron < and ends with a closing chevron >, with the name of the tag between the chevrons. Note that the second tag has a slash / directly before the tag name; this indicates that it’s a closing tag, and therefore marks the end of the paragraph started by the opening <p> tag. The whole paragraph (including tags), <p>Is this HTML?</p> can be called a p-block.

    None of this makes the page display any differently, though; the browser was displaying the contents of the original file as if they were in a paragraph anyway. Some tags that will change the appearance of the text are b – for bold – and i for italic. Try this:

    
    
    <p>Is <i>this</i> <b>HTML</b>?</p>
    

    We’ve got tags within tags now: the italic-tagged text and the bold-tagged text are both inside the paragraph block; this is called a hierarchical structure. It’s like a tree, with the p being the trunk, and b and i being branches. I hope you can see that this wouldn’t make sense:

    
    
    <p>Is <i>this</i> <b>HTML?</p></b>
    

    …although, your browser would actually display that, because it is so lenient.

    Anyway, save this and open it in your browser:

    
    
    <p>Is <i>this</i> <b>HTML</b>?</p>
    

    Click here to see mine. You’ll see that it displays with bold and italic text, like this:


    Is this HTML?


    Any experienced HTML developers reading this over your shoulder will be furiously scratching themselves and calling me a fool for using these exact tags – you’ll see why soon – but just ignore them for the moment.

    Okay, now compare these three snippets:

    
    
    <p>Is <i>this</i> <b>HTML</b>?</p>
    <p>This is certainly a paragraph.</p>
    
    
    
    <p>Is <i>this</i> <b>HTML</b>?</p><p>This is certainly a paragraph.</p>
    
    
    
    <p>Is <i>this</i> <b>HTML</b>?</p>
    
    <p>This is certainly a paragraph.</p>
    

    How do you think they’ll each display?

    The obvious answer is that the first will display the two paragraphs on separate lines, one after the other; the second will display the two paragraphs on one line; and the third will display them on separate lines with a huge gap between them.

    This isn’t true.

    All three cases will display in the same way, like so.

    Why? Because HTML doesn’t care about carriage returns (new lines). It has a rule that says, by default, “paragraph blocks start on new lines”. Even this will display in the same way:

    
    
    <p>Is
    <i>this</i>
    <b>HTML</b>?
    
    </p>
    
    <p>
    
    This is
    certainly
    a paragraph.
    
    </p>
    

    While we’re at it, so will this:

    
    
    <p>Is         <i>this</i>       <b>HTML</b>?</p>
    <p>This is                 certainly              a paragraph.</p>
    

    HTML does care about spaces, but only one at a time. If there are two or more in a row, they get condensed down to one.

    Why? Well, it’s really part of a bigger theme that explains your developer friend’s itchiness:

    Content, Not Presentation

    Whenever a post on any Tuts+ site is tagged “Basix”, our WordPress software automatically adds a tiny speech bubble with a “b” inside over the top of the image at the top of the post . Similarly, my Twitter client is configured so that any Tweets that have been hashtagged “#bieberfever” are displayed in giant bold red text so that I don’t miss them.

    But neither Basix nor #bieberfever imply anything about the presentation of the thing they are attached to; Basix says “this tutorial is written for beginners”, and #bieberfever says “this Tweet is about Justin Bieber”. They each imply something about the content. Their presentations change because of external rules that decide how certain types of content should be displayed.

    HTML follows the same ideals, and that’s why the b and i tags are looked down upon. They only exist because when HTML was invented (about 18 years ago), the creators hadn’t decided on this “separate content from presentation” mindset, so browsers have (again, due to their lenience) continued to display bold and italic tags ever since.

    Still, this doesn’t mean that you can’t use italic or bold text in your HTML files! No, you just have to use different tags, which identify something about the content rather than the presentation. See, when you add italics to a section of text, you’re trying to emphasize the content – so instead of using an i tag, you should use an em tag. And when you make some text bold, you’re trying to strengthen it on the page – so you should use a strong tag.

    Your HTML should therefore look like this:

    
    
    <p>Is <em>this</em> <strong>HTML</strong>?</p>
    <p>This is certainly a paragraph.</p>
    

    By default, your browser will display that in exactly the same way as it did when you used old b and i tags. You may well ask why we’d bother changing it, then – the answer lies in the phrase “by default”.

    Individual web pages – even individual paragraphs – can tell the browser to display em and strong tags differently: suppose you decide that a dotted underline is a better way of strengthening the text, and small caps are a better way of showing emphasis. You can reconfigure em to do one and strong to do the other on your site, and the appearance of all the text will change, without you having to alter the textual content at all. But it wouldn’t make any sense to have the b-for-bold tag display a dotted underline, would it?

    There are a few other tags like b and i that are no longer in use (said to be “deprecated”); you can find out more about any particular tag on W3Schools.

    I’ll explain a bit more about changing the appearance of web pages later on. I can’t explain everything, as it’s a huge subject, with a Tuts+ site all to itself.

    Required Tags

    Okay, so we’ve got a basic HTML page that displays correctly, and contains no deprecated tags. Great! But there are some tags that every HTML page requires, officially. Let’s add them one by one.

    
    
    <html>
    <p>Is <em>this</em> <strong>HTML</strong>?</p>
    <p>This is certainly a paragraph.</p>
    </html>
    

    The html tag says, “hey, browser, this is an HTML document!” To which the browser would presumably respond, “yeah, thanks, I’d guessed that!” if it were a sarcastic human being rather than a piece of software. All of the document should go inside the html tag; to go back to the tree metaphor, html should always be the trunk.

    
    
    <html>
    <body>
    <p>Is <em>this</em> <strong>HTML</strong>?</p>
    <p>This is certainly a paragraph.</p>
    </body>
    </html>
    

    The body contains the actual content of the page. “As opposed to what?” As opposed to…

    
    
    <html>
    <head>
    
    </head>
    <body>
    <p>Is <em>this</em> <strong>HTML</strong>?</p>
    <p>This is certainly a paragraph.</p>
    </body>
    </html>
    

    …the head tag, which contains information about the page, like…

    
    
    <html>
    <head>
    <title>This is an HTML page</title>
    </head>
    <body>
    <p>Is <em>this</em> <strong>HTML</strong>?</p>
    <p>This is certainly a paragraph.</p>
    </body>
    </html>
    

    …the title. If you look at the title bar of your browser with your old HTML page loaded, it’ll just say something like “page.html” (or maybe “Untitled”, or the name of the browser). If you use the code above, though, it’ll say “This is an HTML page”. Note that “This is an HTML page” does not appear anywhere in the actual content of the page, though: this illustrates the difference between the head and the body.

    That HTML is getting a little hard to read now, so you might prefer to use the Tab key to indent the lines:

    
    
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    	</body>
    </html>
    

    Indenting lines like this also helps illustrate that tree-like structure. If you accidentally copied and pasted a tag at the wrong level, it’d be really obvious, like this:

    
    
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    	</body>
    		<p>This is certainly a paragraph.</p>
    </html>
    

    That second paragraph is clearly out of place.

    Doctype

    I’ve mentioned a few times that browsers are very forgiving when trying to display broken (or non-standard) HTML. This is a blessing and a curse.

    It means that sloppy HTML will still be displayed, which is great for anybody that ever makes a mistake i.e. the whole of humankind – but different browsers will display non-standard HTML in different ways.

    It means that the people that make the browsers can come up with all sorts of new tags and features that aren’t part of standard HTML but that do display in their browser, which is great for driving the power of what can be done with HTML forward, beyond the official standards – but not all browsers will support the same set. (For instance, years and years ago, Netscape Navigator allowed you to create blinking text using the <blink> tag, while Internet Explorer allowed you to create text that scrolled across the screen using the <marquee> tag; neither tag was supported by the other browser, and both effects were very annoying.)

    It means that browser developers broke the rules of (or flat out ignored) some areas of the official HTML standards, so that there was a difference between how a page should display, and how it actually looked.

    In a nutshell, it means that, even today, different browsers display the same pages differently.

    To attempt to get around this we have doctypes. For example, stick this at the top of your page (even before the html tag):

    
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
    

    …and the browser will display the page in “quirks mode”, meaning, “using the non-standard practices from the late 90s”. Replace it with this:

    
    
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
    

    …and it’ll display it in “standards mode”, meaning, “using the official HTML standards”. Except, some older browsers that are still in use, like Internet Explorers 6 and 7, still don’t fully follow all the standards. And different browsers still each have their own additional features.

    Doctypes are a mess – there are lots and lots of them – but fortunately we don’t really have to worry about them, here at Activetuts+, because we’re focusing exclusively on HTML5. And HTML5 has only one doctype:

    
    
    <!DOCTYPE html>
    

    Ahhh. Okay, sure, older browsers don’t really know what to do with that, but they can’t handle HTML5 anyway, so it doesn’t matter to us. We’ve just got to hope that today’s browsers stick to the HTML5 standards and don’t get into that old mess again.

    So now you should edit your HTML page to add a doctype:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    	</body>
    		<p>This is certainly a paragraph.</p>
    </html>
    

    It’s a weird tag, because it doesn’t actually enclose anything (there’s no </!DOCTYPE html>), it’s got a space in it, and it’s partly in capitals. That’s because it’s not a tag at all, it just looks a bit like one because of the chevrons. Don’t worry about it.

    Attributes

    Okay, we’ve used this Language to Markup some Text, but what the heck makes that Text so “Hyper”, the H of HTML?

    Hypertext is defined as text, displayed on some sort of electronic device, with hyperlinks to other pieces of text. (The term was coined in the 60s, which explains why it sounds so corny.) And you know what hyperlinks are: bits of text that link to other pages when you click them, like this.

    We create hyperlinks using the a tag – for anchor, because you use it to anchor a URL to some text. No, I don’t know why they didn’t use h or l.

    But this alone isn’t enough:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a>this</a> is a hyperlink.</p>
    	</body>
    </html>
    

    I mean, how could it? There’s no URL there.

    We have to use an attribute of the a tag, like so:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href>this</a> is a hyperlink.</p>
    	</body>
    </html>
    

    We’ve added an href (hypertext reference) attribute to the a tag, which will allow it to hold a URL (though we haven’t specified the URL yet). Note that it’s still an a tag, not an a href tag, and that the closing tag is still </a>, not </a href>; this is why tag names are always a single word, with no spaces.

    To set the href’s value to a specific URL, we use an equals sign, and enclose the URL in quotes:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/">this</a&gt; is a hyperlink.</p>
    	</body>
    </html>
    

    Try it out. Clicking the link will take you to the Activetuts+ homepage.

    Attributes make HTML a lot more powerful. Putting a p tag around some text just says, “this is a paragraph” – it attaches one piece of information to the text – but with attributes we can say so much more; here we’ve said, “the word ‘this’ is an anchor, and it refers to http://active.tutsplus.com/&#8221;.

    Self-Closing Tags

    This is all very plain, so let’s add an image.

    Except… hmm, how exactly do we mark up a piece of text to make it an image? You might guess at something like this:

    
    
    <image href="http://website.com/some_image.png">picture of a cat</image>
    

    …which is a good guess, but not correct.

    In this case, it makes no sense to have the image’s tag – which is img, by the way – tag any text. We write it (without any attributes, for now) like so:

    
    
    <img />
    

    The slash at the end indicates that the tag is closing itself. It’s a bit of a weird concept, and is where the whole idea of tags tagging text falls down a bit. If you prefer, you can call HTML tags elements instead.

    Anyway, let’s insert this into our page:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/">this</a&gt; is a hyperlink.</p>
    		<img />
    	</body>
    </html>
    

    Like the a tag, the img won’t display anything without any attributes. Let’s add some.

    We’ll need an image file to use; this file has to be accessible by anyone reading your page, so while you could use the file path of a picture on your computer, you’d be the only one that could see it.

    I’ll use my Twitter avatar, since that’s online, and hope it doesn’t change before you read this tutorial. It’s: http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png, so, not exactly brief.

    Rather than using href for the attribute that points to this URL, we have to use src (short for “source”) – after all, it’s not actually a hyperlink. So:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/">this</a&gt; is a hyperlink.</p>
    		<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot; />
    	</body>
    </html>
    

    If you load this page, you’ll see my avatar at the bottom – unless I’ve changed it or Twitter has gone down, in which case you’ll see a “broken image” symbol.

    In case the image does break, we can add an alternative piece of text to be shown instead, using the alt attribute:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/">this</a&gt; is a hyperlink.</p>
    		<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    			alt="MichaelJW's Twitter Avatar" />
    	</body>
    </html>
    

    (Remember, HTML doesn’t care about tabs, new lines, and spaces, so it doesn’t matter that I’ve shoved the new attribute on a separate line.)

    Try changing the src URL to one that won’t work (like, http://blahblahblah/), and you’ll see the alternative text (click here for an example). Well, you might, depending on your browser; the HTML 5 standards suggest doing this, but don’t insist on it. Chrome doesn’t do it, much to my surprise.

    Anyway, it’s a good habit to get in to, because it also allows blind people – who are reading your page via text-to-speech software – to hear the contents of the images.

    Nested Tags

    We’ve seen that tags can be nested, as in our case of some italic emphasized text within a paragraph, or paragraphs within a body, but I want to make it clear that you can make things more complex if you wish.

    For example, you can mark up some emphasized text with an anchor:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    			alt="MichaelJW's Twitter Avatar" />
    	</body>
    </html>
    

    …as long as you don’t do something silly like:

    
    
    <p>And <a href="http://active.tutsplus.com/"><em>this</a></em&gt; is a hyperlink.</p>
    

    You can even tag an image with an anchor, as if it were a piece of text:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    	</body>
    </html>
    

    See the results here.

    There are a ton of other tags I could cover, like h1, h2, h3 (etc.) for headings; pre for inserting big blocks of sourcecode or ASCII art (inside which, unusually, HTML does pay attention to extra spaces and new lines); table for inserting tabulated information; input for adding buttons and textboxes; iframe, which lets you insert a whole extra webpage inside the current webpage; and more – but this is enough about the content, because we need to talk about another aspect of HTML.


    Presentation: CSS

    HTML – the language – isn’t concerned with presentation, it’s true. But HTML pages need to be able to modify their presentation, or everything would be Times New Roman with purple links, like in the examples we’ve seen so far!

    For this purpose we have another language, which we embed inside HTML pages, which is all about presentation: Cascading Style Sheets (CSS).

    A Simple Example

    Remember earlier I mentioned that we could make strong tags display with a dotted underline, and em tags display in small caps? We can do that using the CSS language. It looks like this, on its own:

    
    
    strong {
    	border-bottom: 1px dotted;
    }
    
    em {
    	font-variant: small-caps;
    }
    

    Doesn’t look at all like HTML, does it? You can probably read it well enough, though. We have the name of a tag, followed by a pair of curly brackets (“braces”), inside which are all the properties of the text that we wish to set. Each property then has a value, with a colon separating the property from its value, and a semi-colon at the end of each property-value pair. Together, this is called a style sheet. Simple enough.

    We apply a style sheet to the page like so:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    			}
    
    			em {
    				font-variant: small-caps;
    			}
    		</style>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    	</body>
    </html>
    

    Test the page. You’ll see that the word “this” now uses small capitals (in both cases, because they’re both emphasized), and “HTML” has a dotted underline.

    However, the em tag still has an italics effect, and strong is still displaying words in bold. What gives?

    This is what the “Cascading” in “Cascading Style Sheets” refers to: the browser has its own, default CSS styles (like “em” means “italics”), and these cascade down, so that the CSS styles that you apply are simply added on top, rather than replacing the existing ones. It’s as if the browser has a style sheet that looks like this:

    
    
    strong {
    	font-weight: bold;
    }
    
    em {
    	font-style: italic;
    }
    

    (Yes, I know, it’s counter-intuitive not to use the same property to set italics and bold styles.)

    This then cascades down, so that it’s as if the overall style sheet – including your variations – looks like this:

    
    
    strong {
    	font-weight: bold;
    	border-bottom: 1px dotted;
    }
    
    em {
    	font-style: italic;
    	font-variant: small-caps;
    }
    

    Note that your properties are added after the browser’s own. Since the browser computes these properties one at a time, in order, we can cancel out the browser’s styles by changing our set of styles like so:

    
    
    strong {
    	border-bottom: 1px dotted;
    	font-weight: normal;
    }
    
    em {
    	font-variant: small-caps;
    	font-style: normal;
    }
    

    Then, the overall style sheet will look like this:

    
    
    strong {
    	font-weight: bold;
    	border-bottom: 1px dotted;
    	font-weight: normal;
    }
    
    em {
    	font-style: italic;
    	font-variant: small-caps;
    	font-style: normal;
    }
    

    When the browser comes across text that’s been tagged strong, it’ll say, okay, first, I need to make this bold. Then, I need to give it a 1 pixel thick, dotted border, at the bottom of the text. Then, I need to make the font weight normal. Wait, didn’t I make this bold a second ago? Oh well, never mind.

    Result: normal-weighted text, with a dotted border across the bottom. Let’s incorporate this new set of styles into our page:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    				font-weight: normal;
    			}
    
    			em {
    				font-variant: small-caps;
    				font-style: normal;
    			}
    		</style>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    	</body>
    </html>
    

    Load the page. Perfect!

    Other Sources of CSS

    Sticking the style sheet in a style tag within the head of a page is called embedding it, but there are other ways we can affect the overall style of the page.

    For instance, we can put style sheet into its own .css file (called an external style sheet), and tell the page to use it. To do that, we use a place a self-closing link tag within the head, whose rel attribute is stylesheet and whose href tag is the URL of a .css file.

    You should be able to figure out how to write that from the description; try it with the style sheet we use at Activetuts+: http://active.tutsplus.com/wp-content/themes/tuts/style.css. If you need help, expand the code box below.

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<link rel="stylesheet" href="http://active.tutsplus.com/wp-content/themes/tuts/style.css&quot; />
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    				font-weight: normal;
    			}
    
    			em {
    				font-variant: small-caps;
    				font-style: normal;
    			}
    		</style>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    	</body>
    </html>
    

    Click here to see the result. It’s a mess, to be honest, but you can see that it’s loaded the styles.

    External style sheets are applied after the browser’s defaults, but before any embedded ones. This means you can create a single external style sheet to use across your entire web site, and then tweak it by embedded specific styles for each page, if you wish.

    In fact, you can get even more specific, and apply a style to just one single element. This is called an inline style, and it’s done by entering the CSS into the style property of a tag:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<link rel="stylesheet" href="http://active.tutsplus.com/wp-content/themes/tuts/style.css&quot; />
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    				font-weight: normal;
    			}
    
    			em {
    				font-variant: small-caps;
    				font-style: normal;
    			}
    		</style>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    		<p style="color: red;">Check it out, this paragraph is red.</p>
    	</body>
    </html>
    

    Check out the result of the above change. Inline styles are applied after all the other styles.

    Note that you don’t have to enter the name of the element and use curly braces – you’ve already defined which tag you want to style. You can apply multiple styles within the same style attribute; just type them one after the other (no new line needed), and make sure there’s a semi-colon between each of them.

    What if you want to style just a few words within a paragraph? You could wrap them in an em tag, and style that tag like so:

    
    
    <p>Only <em style="font: red;">some of these words</em> are red.</p>
    

    …but then they’ll be in italics too, right? So you cancel that out like so:

    
    
    <p>Only <em style="font: red; font-style: normal;">some of these words</em> are red.</p>
    

    …but that’s no good either, because you can’t guarantee that the em tag doesn’t have other styles attached to it as well – and since you don’t know, you can’t cancel them all out. Fortunately, there’s a tag to help.

    The <span> Tag

    The span tag provides no visual changes by itself, which means it’s perfect for our example above:

    
    
    <p>Only <span style="font: red; font-style: normal;">some of these words</span> are red.</p>
    

    It’s unlikely – not impossible, but unlikely – that someone will have applied certain styles to all span tags in an embedded or an external style sheet, so you should be safe using this.

    Ah, but now look what we’re doing. We’re applying presentation rules right there in the content – exactly the sort of situation that the em and strong tags were invented to avoid! It’s not technically invalid HTML, but it’s still dodgy, and should be used sparingly or not at all.

    However, sometimes you will want to say, “this section of text is different to the others, but none of the existing HTML tags describe that difference very well.” Maybe you’re writing a page about animals, and you decide that it would be useful to tag all the words that represent species – like “cat” and “dog” and so on – so that you can apply an style to all of them at once later.

    HTML doesn’t have a species tag, though. It’s tempting to say, “well, on my website, I’m going to say that the strong tag is always used to represent species” – but this is a bad idea; it’s not what strong is for.

    Instead, you can use classes. Any tag can be given a class like so:

    
    
    <p>I have a <span class="species">cat</span>, a <span class="species">dog</span> and a <span class="species">fish</span>.</p>
    

    Setting a class doesn’t do anything on its own, but you can then define a style for each class in your style sheet:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<link rel="stylesheet" href="http://active.tutsplus.com/wp-content/themes/tuts/style.css&quot; />
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    				font-weight: normal;
    			}
    
    			em {
    				font-variant: small-caps;
    				font-style: normal;
    			}
    
    			.species {
    				outline: 1px dashed blue;
    			}
    		</style>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    		<p style="color: red;">Check it out, this paragraph is red.</p>
    		<p>I have a <span class="species">cat</span>, a <span class="species">dog</span> and a <span class="species">fish</span>.</p>
    	</body>
    </html>
    

    Note that to define a style for a class, rather than a tag, you have to place a dot before its name in the CSS.

    Take a look at the page now. It looks like something you might have found on Geocities about ten years ago, but at least it’s showing some important HTML principles. Classes’ styles are added after embedded styles and before inline ones, so the whole cascading order looks like this:

    • Browser defaults
    • External
    • Embedded
    • Classes
    • Inline

    So, we’ve looked at content and presentation within HTML files. There’s one important aspect left.


    Code: JavaScript

    HTML and CSS are not programming languages. They don’t actually do anything. They just tell text how it is structured and how it should look.

    JavaScript is a programming language. It does stuff.

    One of the simplest examples of JavaScript code is alert('Hello'). When the browser runs this code, it’ll make a little dialog box appear, with the word “Hello” inside.

    Much like with CSS, we can embed JavaScript into a page, add it via an external file, or attach it to a single tag. To embed it, we put it inside a script tag in the head, rather than a style tag:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<link rel="stylesheet" href="http://active.tutsplus.com/wp-content/themes/tuts/style.css&quot; />
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    				font-weight: normal;
    			}
    
    			em {
    				font-variant: small-caps;
    				font-style: normal;
    			}
    
    			.species {
    				outline: 1px dashed blue;
    			}
    		</style>
    		<script>
    			alert('Hello');
    		</script>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    		<p style="color: red;">Check it out, this paragraph is red.</p>
    		<p>I have a <span class="species">cat</span>, a <span class="species">dog</span> and a <span class="species">fish</span>.</p>
    	</body>
    </html>
    

    Check out the result.

    Linking to external JavaScript is easy, too; you put your code in a .js file, and add it to your page like this:

    
    
    <script src="http://example.com/folder/someCode.js"></script&gt;
    

    So, it’s the same tag as we used to embed some code, except it’s empty, and it has a src attribute. I’m not going to give an example of this, but feel free to try your own.

    Inline JavaScript – i.e., attaching code to specific elements – works a little differently than inline CSS. A first guess at how we could do this might be:

    
    
    <span script="alert('Hello')">Some code is attached to this text.</span>
    

    …but, if you think about it, this doesn’t make sense. When would the alert appear? When the page loaded? When that specific section of text loaded? When it was on the page? When it was clicked? You can’t guess, and neither can the browser.

    Instead, there are a whole bunch of attributes that you can stick JavaScript into; they’re called event attributes, and they trigger the JavaScript inside them for different reasons.

    For instance, one such attribute is onclick, which triggers the JavaScript inside it whenever the user clicks the contents of the tag with their mouse. It looks like this:

    
    
    <!DOCTYPE html>
    <html>
    	<head>
    		<title>This is an HTML page</title>
    		<link rel="stylesheet" href="http://active.tutsplus.com/wp-content/themes/tuts/style.css&quot; />
    		<style type="text/css">
    			strong {
    				border-bottom: 1px dotted;
    				font-weight: normal;
    			}
    
    			em {
    				font-variant: small-caps;
    				font-style: normal;
    			}
    
    			.species {
    				outline: 1px dashed blue;
    			}
    		</style>
    		<script>
    			alert('Hello');
    		</script>
    	</head>
    	<body>
    		<p>Is <em>this</em> <strong>HTML</strong>?</p>
    		<p>This is certainly a paragraph.</p>
    		<p>And <a href="http://active.tutsplus.com/"><em>this</em></a&gt; is a hyperlink.</p>
    		<a href="http://twitter.com/MichaelJW/"&gt;
    			<img src="http://a3.twimg.com/profile_images/1403171562/VectorMJWSquareTransparent.png&quot;
    				alt="MichaelJW's Twitter Avatar" />
    		</a>
    		<p style="color: red;">Check it out, this paragraph is red.</p>
    		<p>I have a <span class="species">cat</span>, a <span class="species">dog</span> and a <span class="species">fish</span>.</p>
    		<p onclick="alert('I can see it in your eyes...')">Is it me you're looking for?</p>
    	</body>
    </html>
    

    Load the page and click the last paragraph – yes, you can click it, even though it’s not a hyperlink. Tada! You’re half-way to programming a duet.

    That’s Not All

    I’m not going to go into a lot of detail on JavaScript here, because that’s what the bulk of our future HTML5 tutorials are going to focus on. However, you should know that JavaScript can do a lot more than make annoying dialog boxes appear.

    Besides making the browser do stuff on its own, JavaScript can alter and create HTML (as well as CSS and JavaScript code itself). It’s hard to overstate how powerful that makes it.

    And as if that weren’t enough: if you’re using Chrome, you can play Angry Birds in your browser, written in JavaScript, HTML, CSS… and, okay, a touch of Flash for the sounds.


    What Next?

    If you’re interested in learning more about the design and appearance of webpages, check out our sister site Webdesigntuts+. One of our other sister sites, Nettuts+, has already published a lot of articles on HTML, CSS, and JavaScript that you should dig in to.

    We’ll be focusing on the latest version of HTML – HTML5 – and using it to create apps and games for modern browser. If you want to keep up to date with what we’re doing, then you can follow us on Twitter, like us on Facebook, subscribe to us through RSS, or sign up to our free email newsletter.

    Here’s one last tip for the curious: you can view the HTML of any web page on the Internet by right-clicking a blank area and selecting “View Source”. I should warn you: some sites make the markup all messy so that you can’t read (and copy) it; some sites’ markup is just naturally messy. But try it out!


  5. Michael James Williams says:
    September 15, 2011 at 10:40 pm

    Artificial intelligence is a popular programming topic, with obvious applications in game development, and machine learning is a branch of AI focused on creating code that can learn based on past experiences. Databases are perhaps not as stereotypically cool to study, but still very important for any programmer. Stanford University is offering free, online, undergraduate-level courses in each subject. Read on to find out how you can enroll…


    Are These Proper University Courses?

    Yes and no. The courses are online versions of those which actual Stanford students will take (other than being delayed by a couple of weeks), and so will be taught and graded at university level – but studying online won’t get you a Stanford certificate or university credit, so you won’t be able to put “attended Stanford university” on your CV.

    Still, you’ll get the lectures (in video format) and the homework and exams (which you can submit and have graded electronically), so you’ll be learning the same material as the Stanford students!


    What’s Being Taught?

    Three courses are on offer:

    Introduction to Artificial Intelligence

    You’ll need to brush up on your probability and linear algebra skills (perhaps you could try Khan Academy).

    For more information, and to enroll, visit ai-class.com.

    Machine Learning

    Again, you’ll need to be familiar with basic probability theory and linear algebra.

    For more information, and to enroll, visit ml-class.com.

    Introduction to Databases

    This isn’t just about relational databases and SQL; it also covers XML (including XPath, XQuery and XSLT), UML, and “NoSQL” systems.

    For more information, and to enroll, visit db-class.com.


    Is There a Deadline?

    Yes. This isn’t like Tuts+ Premium, where you sign up and have access to courses and tutorials to read at your leisure; everybody taking the online course starts at the same time, with new lectures released each week and homework assignments due in on certain dates.

    The courses all start on the 10th of October, and end in mid-December, so you should enroll before they start.

    If you don’t have time, or simply don’t want, to do the homework assignments, you can opt to take the “basic track” – in the AI course at least – which has the same material, but without the homework or exams. You can downgrade to this at any time, so there’s no harm in signing up to the “advanced track” for now.

    If you’re interested in programming, I hope you’ll sign up to at least one of the courses – not just because of the content, but because this should be a really interesting experiment in online learning.


  6. Matt Stuttard says:
    September 15, 2011 at 10:41 pm

    We’ve got another Activetuts+ Exclusive Freebie for you! This time, Matt Stuttard (aka MSFX) is offering you his brand new debugging utility, Tr.ace(), which adds some very useful extra features to Flash’s trace() function. Read on to find out more, and to download your copy.

    All developers use some form of tracing as a loose method of debugging at some point whilst developing their applications. The problem with the trace statement within AS3 though is that it’s rather limited. If you’re working within a team it’s possible you’ve no idea who’s trace is whose or where any of the traces are coming from, and there’s no automated formatting to help distinguish traces from different users and classes!

    Wouldn’t it be awesome if you could restrict your applications’ trace statements to specific classes or particular users, or even completely ignore traces from specific users or classes altogether?

    Wouldn’t it be great to have a little more control over the formatting of your traces so that you’d know who traced it, the class it’s traced from, and the time the trace was executed?

    How about the ability to add automatic linebreaks between each trace, and neatly trace out complex, nested Arrays and Objects, all while automatically copying the output to the clipboard?

    Welcome to Tr.ace()!


    Downloading Tr.ace()

    Tr.ace() is an open source library that’s available to download here at Activetuts+ in ZIP format, and is also available as a public repository on my GitHub for those who are little more nerdy or who wish to fork and/or contribute towards the Tr.ace() library.

    The library is AS3-only and has two separate repositories: one for Flash Player 9 and one for Flash Player 10+.

    To use the Tr.ace() library you must download and extract one of the above source packages, and then copy the ‘uk’ directory, located within the ‘src’ directory, into your global classpath directory. You’re then all set to go!

    (Any problems? Check out this extensive guide to using an external library in your Flash projects.)


    Configuring Tr.ace()

    Firstly, a little theory and explanation.

    Tr.ace() is a library focused on tracing. ‘Tr’ is the main class and ‘ace()’ is a function of the Tr class, hence the library name Tr.ace().

    The name of the library also illustrates the library’s usage. As ‘Tr’ is a static class you don’t need to create an instance of it to use its functions or configure any of its settings; you simply use Tr.whateverTheValue or Tr.whateverTheFunction().

    Lastly, because the internal workings of the library use the Singleton Design Pattern, any of the settings you apply to Tr.ace() only need applying once within your application – I’d suggest within your Document / Main Class.

    There are two versions of the library, one for Flash Player 9 and one for Flash Player 10 and up. The only difference (currently) is that the Flash Player 10 version supports automatic copying to the Clipboard.

    Lets now take a look at some of these settings (the following are excerpts from ExampleMain.as, which can be found in the src directory) :

    		// restrict the trace output(s) to only the 'ExampleClass2' Class
    		Tr.restrictToClasses = [ExampleClass2];
    
    		// ignore the trace output(s) from the 'ExampleMain' Class only
    		Tr.ignoreClasses = [ExampleMain];
    
    		// restrict the trace output(s) from user 'MSFX' only
    		Tr.restrictToUsers = [TrUsers.MSFX];
    
    		// ignore the trace output(s) from user 'MSFX' only
    		Tr.ignoreUsers = [TrUsers.MSFX];
    

    As you should be able to see from the above examples it’s easy to very quickly tailor your output to either restrict the output to only be from specific users or classes, or to ignore the output from specific users or classes.

    As the below examples also demonstrate, it’s very easy to toggle linebreaks, timestamps and copying to the clipboard (FP10 only). You can also very easily switch tracing off all together.

    		// show the time with each trace
    		Tr.useTimeStamp = true;
    
    		// copy the trace output to the clipboard (non IDE debugging - FP10 only)
    		Tr.copyToClipboard = true;
    
    		// add linebreaks between each output
    		Tr.useLineBreaks = true;
    
    		// switch tracing off entirely
    		Tr.off = true;
    

    Lets now have a quick look over the functions available within the Tr.ace() library.


    Tr.ace(…)

    The Tr.ace(…) function requires three parameters: the output, the username and the class being traced from.

    All three of these parameters are required, to allow the library to restrict to or ignore traces from particular users or classes; if you’re worried about this taking longer to type than a usual trace you can wrap it up as a Code Snippet in your favourite IDE – more later.

    
    
    // A String as the output from user MSFX within the Class 'ClassName'.
    Tr.ace("here is the output", TrUsers.MSFX, ClassName);
    
    // Sum of several numbers as the output from user DEFAULT within the Class 'AnotherClassName'.
    Tr.ace( ((1 + 2.5 + 6.999) * 12), TrUsers.DEFAULT, AnotherClassName);
    
    // tracing a variable as the output from user MSFX within the Class 'YetAnotherClassName'.
    Tr.ace("variable equals: " + variableName, TrUsers.MSFX, YetAnotherClassName);
    	

    Tr.aceArray(…)

    The Tr.aceArray(…) function requires three parameters: the Array, the username and the class being traced from.

    All three of these parameters are required, to allow the library to restrict to or ignore traces from particular users or classes; if you’re worried about this taking longer to type than a usual trace you can wrap it up as a Code Snippet in your favourite IDE – more later.

    
    
    // A String as the output from user MSFX within the Class 'ClassName'.
    Tr.aceArray("here is the output", TrUsers.MSFX, ClassName);
    
    // Sum of several numbers as the output from user DEFAULT within the Class 'AnotherClassName'.
    Tr.aceArray( ((1 + 2.5 + 6.999) * 12), TrUsers.DEFAULT, AnotherClassName);
    

    Tr.aceMulti(…)

    The Tr.aceMulti(…) function requires a mimimum of three parameters: the username, the class being traced from and an unlimited list of arguments (seperated via commas) to trace out. Note that these parameters are in a different order than in the other functions.

    All three of these parameters are required, to allow the library to restrict to or ignore traces from particular users or classes; if you’re worried about this taking longer to type than a usual trace you can wrap it up as a Code Snippet in your favourite IDE – more later.

    
    
    // A String as the output from user MSFX within the Class 'ClassName'.
    Tr.aceMulti("here is the output", TrUsers.MSFX, ClassName);
    
    // Sum of several numbers as the output from user DEFAULT within the Class 'AnotherClassName'.
    Tr.aceMulti( ((1 + 2.5 + 6.999) * 12), TrUsers.DEFAULT, AnotherClassName);
    	

    Tr.aceObject(…)

    The Tr.aceObject(…) function requires three parameters: the Object, the username and the class being traced from.

    All three of these parameters are required, to allow the library to restrict to or ignore traces from particular users or classes; if you’re worried about this taking longer to type than a usual trace you can wrap it up as a Code Snippet in your favourite IDE – more later.

    
    
    // A String as the output from user MSFX within the Class 'ClassName'.
    Tr.aceObject("here is the output", TrUsers.MSFX, ClassName);
    
    // Sum of several numbers as the output from user DEFAULT within the Class 'AnotherClassName'.
    Tr.aceObject( ((1 + 2.5 + 6.999) * 12), TrUsers.DEFAULT, AnotherClassName);
    	

    Adding Users to the Tr.ace() Library

    You may have noticed several pre-existing usernames within the Tr.ace() library such as TrUsers.DEFAULT and TrUsers.MSFX in the above examples. To remove the chance of typos it’s recommended that you add your name as a Static Constant to the Tr.ace() Library as with the pre-existing usernames.

    To add yourself to the library, open the ‘TrUsers.as’ file located at ‘uk/msfx/utils/tracing/users/TrUsers.as’. Add your own user name as a public static constant to the bottom of the list and you’re ready to go!

    
    
    /**
     * Your username!
     */
    public static const MATT:String = "Matt";
    	

    Using Tr.ace() With Code Snippets

    Although Tr.ace() provides lots of advantages over using the usual trace() statement within Flash there is quite a lot more to type, which could potentially slow down your development. Enter Code Snippets.

    Code Snippets are exactly what you’d think: automatically-inserted snippets of code. Most IDEs, if not all, support them and they speed up your development like you’re Superman. I use FlashDevelop (and you should too!) so let’s quickly have a look at adding a new code snippet for Tr.ace().

    The code snippet must be usable wherever you decide to add it to your application with as little adjustments as possible. With Tr.ace() you must provide both the user tracing and the Class traced from along with the output. The user is easy enough to wrap up in the code snippet since it’ll likely not change very often; however, it’s likely we’ll trace from different Classes quite often.

    Therefore, instead of entering the class manually each time, we can use a simple piece of code to return the class we’re tracing from automatically. I performed some tests using Grant Skinners Performance Harness on different approaches of achieving this and found the method below to be the most efficient (other than using the actual class name itself). You can find the results within the src directory.

    If you’re using FlashDevelop, open the Code Snippets Panel and click ‘Add’ to create a new snippet. (There’s bound to be a similar menu option in whatever IDE you use.)

    code snippets menu

    Add a new snippet and call it whatever you want (I used ‘tr’) and add the main body to the snippet – with your own username of course. Object(this).constructor returns the Class from which the function is called, no matter where you enter this line in your project.

    adding snippet

    Add the entry point where the output for the trace should go.

    adding entry point to snippet

    Finally, click ‘Save’.

    adding entry point to snippet

    Code snippet complete! To use the snippet within FlashDevelop, simply press Ctrl+B, type ‘tr’ and hit Enter. Then, type in whatever you want to trace.


    Documentation for Tr.ace()

    Within the download package you’ll find a ‘docs’ directory, open the ‘index.html’ file to view the ASDocs-generated Documentation for Tr.ace(). You can also find the documentation online: http://docs.msfx.co.uk/as3/trace/.


    Happy Tracing!

    So, that’s it really. If you have any questions or suggestions for the library feel free to get in touch in the comments.

    Happy Tracing!


  7. Eduardo Gonzalez says:
    September 15, 2011 at 11:09 pm

    Twice a month, we revisit some of our readers’ favorite posts from throughout the history of Activetuts+. This week’s retro-Active Quick Tip, first published in June 2010, is an introduction to a popular (but commonly mis-used) design pattern.

    In this Quick Tip we are going to talk about the Singleton design pattern and how it can help you to optimize your code when you need exactly one instance of a class.


    Step 1: Introduction

    As a programmer you must be aware that there are some cases where you want to use an instance of a class, but you want to create just one and keep it throughout the entire program. Well, that’s what Singletons are for.


    Step 2: What is a Singleton?

    A Singleton is a Object-Oriented Design Pattern used by many programmers; it lets you create a sort of “global” instance of a class. It is created in such a way that only one unique instance can exist, so that all instances of that class are in exactly the same state.


    Step 3: Why Would We Use it?

    The most common example would be a score – for example a football score. You would have a Score class, with properties homeTeamScore and awayTeamScore and a method like increaseScore(team:Team).

    Both teams must be able to increase their score when they make a goal, but you can’t give each team their own Score instance; you want both to access and modify the same one.

    This is a case where a Singleton is a perfect solution, since it could work as a global instance that anybody can access; you will have just one instance for everyone, so you don’t have to worry that each team will be modifying a different score.


    Step 4: Singleton Class

    Now let’s start creating a singleton in AS3, but first remember the key elements of a singleton:

    • Anyone must be able to access it.
    • Just one instance can be created.

    Create a new AS3 class and call it Singleton.as.

    (Not familiar with class-based coding? Check out this quick intro.)

    Here’s the basic Singleton code:

    package  {
    
    	public class Singleton {
    
    		private static var instance:Singleton;		//This will be the unique instance created by the class
    		private static var isOkayToCreate:Boolean=false;	//This variable will help us to determine whether the instance can be created
    
    		public function Singleton() {
    			//If we can't create an instance, throw an error so no instance is created
    			if(!isOkayToCreate) throw new Error(this + " is a Singleton. Access using getInstance()");
    		}
    
    		//With this method we will create and access the instance of the method
    		public static function getInstance():Singleton
    		{
    			//If there's no instance, create it
    			if (!instance)
    			{
    				//Allow the creation of the instance, and after it is created, stop any more from being created
    				isOkayToCreate = true;
    				instance = new Singleton();
    				isOkayToCreate = false;
    				trace("Singleton instance created!");
    			}
    			return instance;
    		}
    	}
    }
    

    Step 5: Create a Flash Project

    Now let’s go and test the Singleton, first create a new Flash file named Main.fla. On the properties panel set the class also to Main.


    Step 6: Create a Singleton

    Create a new class named “Main” and create an instance of Singleton using the constructor:

    package
    {
    
    	import flash.display.MovieClip;
    
    	public class Main extends MovieClip
    	{
    		public function Main()
    		{
    			var testSingleton:Singleton = new Singleton();
    		}
    	}
    }
    

    Save and run it, you will see that it throws an error telling us to use the getInstance() function instead, so go ahead and do that:

    package
    {
    
    	import flash.display.MovieClip;
    
    	public class Main extends MovieClip
    	{
    		public function Main()
    		{
    			var testSingleton:Singleton = Singleton.getInstance();
    		}
    	}
    }
    

    Save and run it, there’s no error now, and you can see in the console the text “Singleton instance created!”, meaning that it was created successfully.

    So when you use a Singleton class, you cannot use new Singleton(), you have to use Singleton.getInstance() instead.


    Step 7: Add Properties to the Class

    The Singleton isn’t very useful at the minute. Let’s add a property:

    package  {
    
    	public class Singleton {
    
    		private static var instance:Singleton;		//This will be the unique instance created by the class
    		private static var isOkayToCreate:Boolean=false;	//This variable will help us to determine whether the instance can be created
    
    		//new example property:
    		public var exampleProperty:String = "This is an example";
    
    		public function Singleton() {
    			//If we can't create an instance, throw an error so no instance is created
    			if(!isOkayToCreate) throw new Error(this + " is a Singleton. Access using getInstance()");
    		}
    
    		//With this method we will create and access the instance of the method
    		public static function getInstance():Singleton
    		{
    			//If there's no instance, create it
    			if (!instance)
    			{
    				//Allow the creation of the instance, and after it is created, stop any more from being created
    				isOkayToCreate = true;
    				instance = new Singleton();
    				isOkayToCreate = false;
    				trace("Singleton instance created!");
    			}
    			return instance;
    		}
    	}
    }
    

    Now, in Main.as, you can access testSingleton.exampleProperty just as if it were a normal class. Try tracing it out.


    Step 8: Try Creating Another Singleton

    To prove that the Singleton does what it’s supposed to do, create another singleton and change the example property of one of them:

    package
    {
    
    	import flash.display.MovieClip;
    
    	public class Main extends MovieClip
    	{
    		public function Main()
    		{
    			var testSingleton:Singleton = Singleton.getInstance();
    			var anotherSingleton:Singleton = Singleton.getInstance();
    			anotherSingleton.exampleProperty = "This is set in anotherSingleton";
    			trace(testSingleton.exampleProperty, anotherSingleton.exampleProperty);
    		}
    	}
    }
    

    What do you think will happen?

    This even works if you create the Singleton variables in different classes.


    Conclusion

    The singleton pattern can be used on any code, and I highly recommend it if you are going to use just one instance of a class since it gives you better control of it. I hope you liked this Quick Tip, thanks for reading!

    Saludos -Eduardo


  8. John Reyes says:
    September 15, 2011 at 11:35 pm

    This two-part tutorial will cover creating a multi-state car using a finite state machine. We will start with Procedural FSM and progress into the State Pattern design pattern. Concept and creation will be our main focus during this first part; we will then proceed into application and extension during the second part.


    Final Result Preview

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


    What Is a Finite State Machine?

    Wikipedia defines an FSM (Finite State Machine) as a mathematical abstraction sometimes used to design digital logic or computer programs. It is a behavior model composed of a finite number of states, transitions between those states, and actions, similar to a flow graph in which one can inspect the way logic runs when certain conditions are met.

    It has finite internal memory; an input feature that reads symbols in a sequence, one at a time, without going backward; and an output feature, which may be in the form of a user interface, once the model is implemented. The operation of an FSM begins from one of the states (called a start state), goes through transitions (depending on the inputs) to different states, and can end in any of those available – however, only a certain set of states mark a successful flow of operation.

    In my own words, an FSM is a device used by developers to create objects that have different behaviors determined by the current state they are in. Depending on the input, the object can react and/or transition to a different state.

    One good example would be a 1970 HK VP70Z machine pistol, which has three firing modes: safety, single shot, and semi-automatic three-round burst. Depending on the current mode you have it set to (state), the result (output) is different when you pull the trigger (input).

    Tools: When conceptualizing an idea (the multi-state object you’re trying to create), it’s best to use a State Transition Table to know what states and actions for those states you will need to add.


    Step 1: Setup

    It’s time to start a new project. With FlashDevelop, create a new AS3 project. For the name, put CarFSM. Click “Browse…” and save it to your desired location. Go into the Package slot and enter “com.activeTuts.fsm”. Make sure the “Create directory for project” checkbox is selected then click “OK” to finish.

    description of image

    Once the project is loaded in FlashDevelop, click “View” and select “Project Manager”. See the “src” folder? Right-click that and choose “Explore”.

    description of image

    When you have that folder open, you should see the “com” folder you created earlier. Open the sourcecode I’ve included with this tutorial and drag the “assets” folder into “src”; make sure you don’t drop it into the “com” folder.

    Next, go inside the sourcecode “com” folder and drag the “bit101″ folder into the “com” folder inside “src”. You can also download minimalComps here if you prefer getting it straight from the source.

    Finally, drill down inside the “com” folder (within “src”) all the way into “fsm” and double-click Main.as. This should now be open inside FlashDevelop (assuming you have FD as your default .as extension application).


    Step 2: Warm Up

    We’ll start by considering the two states of an even more simple example: MinimalComps’s Checkbox.

    Let’s say we want a Checkbox that will reflect its current state by changing its label. Below is the Transition Table for the Checkbox.

    description of image

    Now for the code. Inside Main.as, one line below the class imports, add the metadata shown below.

    
    
    [SWF (width = 500, height = 350, frameRate = 60, backgroundColor = 0xFFFFFF)]
    

    Next, go inside the init() method and set your cursor below where it says “entry point”. Then add a method call simpleExample(). Next, make sure you have the cursor active somewhere inside the method call, and press the “CTRL + SHIFT + 1″ keys. A prompt will show; pick “Generate private function” and hit the “Enter” key.

    description of image

    Now just copy and paste the code below inside the newly created method. Next, put your cursor inside the word “CheckBox” and press “CTRL + SHIFT + 1″ to automatically import the required class. Once done, hit “CTRL + ENTER” to run the application.

    From here on, if you run into any errors, please compare your classes with the ones I’ve included with the source download.

    
    
    var checkBox:CheckBox = new CheckBox (this, 240, 160, 'false', showValue);
    checkBox.scaleX = checkBox.scaleY = 2;
    
    function showValue (e:Event):void
    {
    	CheckBox (e.target).label = Boolean (e.target.selected).toString ();
    }
    

    You should have something similar to what you see above this line. There are your two states, ON and OFF. Every time you click , the checkbox toggles states and also changes its label as a form of output.

    On to the real “Car” FSM project. Make sure you have the project set to run in “debug” mode to enable trace() statements.


    Step 3: The Procedural Car FSM

    Okay, let’s forget the preview at the top of the page and start the Car FSM from scratch. In Main.as, highlight the init() method along with the simpleExample() method and hit the “BACK” key to remove them.

    Go one line above the constructor and add the variables below.

    
    
    private var _past:Number;
    private var _present:Number;
    
    private var _tick:Number;
    
    private var _car:Car;
    
    private var _initiatedTest1:Boolean;
    private var _initiatedTest2:Boolean;
    private var _initiatedTest3:Boolean;
    private var _initiatedTest4:Boolean;
    private var _initiatedTest5:Boolean;
    private var _initiatedTest6:Boolean;
    
    private var _finalActions:Boolean;
    
    private var _counter:Number = 0;
    

    The variables _past, _present, _tick, and _counter will all be used for timed execution. I’ll explain more about that soon. The _car variable will hold reference for the Car class that will encapsulate the procedural Car FSM actions. The rest are Boolean properties used for triggering timed actions.

    Let’s work on the timed execution. Add the code below inside the constructor.

    
    
    _present = getTimer ();
    
    trace ('Start of constructor = ' + _present * 0.001 + ' seconds\n');
    
    _past = _present;
    
    addEventListener (Event.ENTER_FRAME, update);
    

    Get your cursor inside the word “update” and press “CTRL + SHIFT + 1″ and choose “Generate Event handler”. When you test the application, you’ll see a print out similar to “Start of constructor = 2.119 seconds” (it could be less if you have a faster PC). It’s the same as dividing the value of getTimer() with 1000 but they say multiplication is faster.

    Let’s proceed to the update() method. Add the code below into it.

    
    
    _present = getTimer ();
    _tick = (_present - _past) * .001; ///converted to 1/1000 milliseconds
    _past = _present;
    
    _counter += _tick; ///used for tests with timed execution.
    
    if (_counter >= 2)//2 seconds
    {
    	_counter -= 2;
    	trace (_counter + ' 2 seconds');
    }
    

    Now, when you test it again, you’ll notice a trace() statement pop-out every two seconds. The _counter is then reset to whatever overlap it had to maintain timing accuracy.

    Try using a different value other than two seconds and run it a couple more times.

    On to the Car class. Before proceeding, go ahead and remove that if() statement inside the update() method.


    Step 4: The Car Class

    As I mentioned earlier, we’re starting with a fresh idea of creating a multi-state car. Let’s say we decided to have a car that can be turned on and off, also driven forward and can run out of gas. That would give us four different states – ON, OFF, DRIVE_FORWARD, and OUT_OF_FUEL.

    The very first thing to do is work out the different states and actions for those states in a State Transition Table. You can use a pencil and a blank piece of paper to quickly jot down all the states and actions the Car object would need. See the image below.

    description of image

    Always have an " update()" method to have real time control over your states. Like consume a higher amount of fuel when driving than when the engine’s idling at park.

    It’s easy to tell how each state should respond for each of the actions. It seems simple because we (being human) all think of objects to be in one state or another.

    Now we’re ready to code the class.

    Inside the constructor method in Main.as, go one line before the ENTER_FRAME event listener and add the code below.

    
    
    _car = new Car;
    addChild (_car);
    

    Now since there is no Car class, get your cursor inside the “Car” word and press “CTRL + SHIFT + 1″, select “Create new class” and hit the “ENTER” key.

    Use the same information as shown below. Click “OK” to finish.

    description of image

    You should now have the Car class open in FlashDevelop.


    Step 5: Car Variables

    Add the code below one line above the class constructor.

    
    
    public static const ONE_SIXTH_SECONDS:Number = 1 / 6; //6 times per second
    
    private const IDLE_FUEL_CONSUMPTION:Number = .0055;
    private const DRIVE_FUEL_CONSUMPTION:Number = .011;
    
    ///CAR STATES
    private static const ENGINE_OFF:String = 'off';
    private static const ENGINE_ON:String = 'on';
    private static const ENGINE_DRIVE_FORWARD:String = 'driving forward';
    private static const ENGINE_OUT_OF_FUEL:String = 'out of fuel';
    
    private var _currentState:String = ENGINE_OFF;
    
    private var _engineTimer:Number = 0;
    private var _fullCapacity:Number = 1;
    private var _fuelSupply:Number = _fullCapacity; //in gallons
    

    The Car is setup to only consume fuel 6 times per second. This is represented by the class constant ONE_SIXTH_SECONDS. In addition, the consumption amount depends if the car is on idle or driving forward. We’ll use IDLE_FUEL_CONSUMPTION and DRIVE_FUEL_CONSUMPTION for those purposes.

    The four states are represented by String constants with ENGINE_OFF set as default.

    The _engineTimer property will be used to trigger consumeFuel() every 1/6 seconds but only if the state is either ENGINE_ON or ENGINE_DRIVE_FORWARD.

    Finally, _fuelSupply (which is what consumeFuel() will slowly take away) takes in the value of _fuelCapacity for a full tank.


    Step 6: Methods From the State Transition Table

    Leave the Car constructor empty for now. Go below it and add the update() method shown below.

    
    
    public function update ($tick:Number):void
    {
    
    	switch (_currentState)
    	{
    		case ENGINE_OFF:
    		//nothing
    		break;
    
    		case ENGINE_ON:
    		_engineTimer += $tick;
    
    		//gas consumption and trace statement
    		if (_engineTimer >= ONE_SIXTH_SECONDS) //6 times per second interval
    		{
            	trace ('vm');//you may comment this out if you like
    			_engineTimer -= ONE_SIXTH_SECONDS; // 0 + overlap
    
    			consumeFuel (IDLE_FUEL_CONSUMPTION);///30 seconds gas supply
    		}
    		break;
    
    		case ENGINE_DRIVE_FORWARD:
    		_engineTimer += $tick;
    
    		if (_engineTimer >= ONE_SIXTH_SECONDS)
    		{
            	trace ('vroomm');//you may comment this out if you like
    			_engineTimer -= ONE_SIXTH_SECONDS;
    
    			consumeFuel (DRIVE_FUEL_CONSUMPTION);///15 seconds gas supply
    		}
    		break;
    
    		case ENGINE_OUT_OF_FUEL:
    		//nothing
    		break;
    	}
    }
    

    We’ll have Main.as call this method at every ENTER_FRAME event passing in the elapsed time between frames. Once called, it checks the Car’s current state and runs the appropriate action.

    If left alone, state transition can only occur through consumeFuel() which sets it to OUT_OF_FUEL when _fuelSupply runs out.

    Note: Actions that are on your State Transition Table will always be public access used as input controls. This holds true whether you’re using Procedural FSM or the State Pattern.


    Step 7: Turning the Car On

    Add the code below after the update() method.

    
    
    public function turnKeyOn ():void
    {
    	trace ("attempting to turn the car on...");
    
    	switch (_currentState)
    	{
    		case ENGINE_OFF:
    		trace ("Turning the car on...the engine is now running!");
    		_currentState = ENGINE_ON;
    		break;
    
    		case ENGINE_ON:
    		trace ("the engine's already running you didn't have to crank the ignition!");
    		break;
    
    		case ENGINE_DRIVE_FORWARD:
    		trace ("you're driving so don't crank the ignition!");
    		break;
    
    		case ENGINE_OUT_OF_FUEL:
    		trace ("no fuel - the car will not start, get some fuel before anything. Returning the key to the off position.");
    		break;
    	}
    }
    

    Just like the update() method, _currentState is checked and the appropriate action is run. It pretty much explains itself.


    Step 8: Turning the Car Off.

    The same goes for turning the Car off. Add it next.

    
    
    public function turnKeyOff ():void
    {
    	trace ("attempting to turn the car off...");
    
    	switch (_currentState)
    	{
    		case ENGINE_OFF:
    		trace ("The car's already off, you can't turn the key counter-clockwise any further...");
    		break;
    
    		case ENGINE_ON:
    		trace ("click... the engine has been turned off from park.");
    		_currentState = ENGINE_OFF;
    		break;
    
    		case ENGINE_DRIVE_FORWARD:
    		trace ("nvrm...click... rolling to a stop...the engine has been turned off.");
    
    		_currentState = ENGINE_OFF;
    		break;
    
    		case ENGINE_OUT_OF_FUEL:
    		trace ("you already did this when the fuel ran out earlier...");
    		break;
    	}
    }
    

    It becomes very easy to create the methods. Just copy and paste the previous one, then make a few changes here and there.


    Step 9: Driving Forward

    Always go back to your State Transition Table to see what needs to happen for each state when you call the input method you’re currently working on.

    Add the code below the turnKeyOff() method.

    
    
    public function driveForward ():void
    {
    	trace ("attempting to drive forward...");
    	switch (_currentState)
    	{
    		case ENGINE_OFF:
    		trace ("click, changing the gear to drive doesn't do anything...the car is not running, returning the gear to park...");
    		break;
    
    		case ENGINE_ON:
    		trace ("click, changing gears to drive ...now were going somewhere...");
    		_currentState = ENGINE_DRIVE_FORWARD;
    		break;
    
    		case ENGINE_DRIVE_FORWARD:
    		trace ("already driving - no need to change anything...");
    		break;
    
    		case ENGINE_OUT_OF_FUEL:
    		trace ("click, changing the gear to drive won't do anything...the car has no fuel, returning the gear to park...");
    		break;
    	}
    }
    

    Step 10: Consuming Fuel

    This method is private since only the Car needs access to it. It’s called six times per second from update().

    Put the code next after the driveForward() method.

    
    
    private function consumeFuel ($consumption:Number):void
    {
    
    	if ((_fuelSupply -= $consumption) <= 0)
    	{
    		_fuelSupply = 0;
    		trace ("phit...phit - the engine has stopped, no more fuel to run, returning the gear to park...");
    		_currentState = ENGINE_OUT_OF_FUEL;
    	}
    }
    

    Now you see how the code goes as explained earlier at the Class variables section.


    Step 11: Refueling the Car

    This method is private since only the Car needs access to it.

    Put the code next.

    
    
    public function reFuel ():void
    {
    	trace ("attempting to refuel...");
    
    	if (_fuelSupply == 1)
    	{
    		trace ("no need to refuel right now, the tank is full.");
    		return;
    	}
    
    	switch (_currentState)
    	{
    		case ENGINE_OFF:
    		trace ("getting out of the car and...");
    		break;
    
    		case ENGINE_ON:
    		trace ("turning the key to off position, getting out of the car and...");
    		_currentState = ENGINE_OFF;
    		break;
    
    		case ENGINE_DRIVE_FORWARD:
    		trace ("changing gear from drive to park and turning the key to off position, getting out of the car and...");
    		_currentState = ENGINE_OFF;
    		break;
    
    		case ENGINE_OUT_OF_FUEL:
    		trace ("turning the key to the off position, getting out of the car and...");
    		_currentState = ENGINE_OFF;
    		break;
    	}
    
    	var neededSupply:Number = _fullCapacity - _fuelSupply;
    
    	_fuelSupply += neededSupply;
    	trace ("filling up to " + _fuelSupply + " gallon(s) of fuel.");
    }
    

    The method first checks to see if the Car has a full tank. If so, it tells you it has a full tank and exits the method.

    If the Car doesn’t have a full tank on the other hand, it goes through the familiar case/switch statement and runs the proper trace() statement.

    The last bit of code calculates the amount of consumed fuel and replenishes only that to keep a full tank. It then prints the value of a full tank.


    Step 12: Using toString() to Help trace() Statements

    This method had to be overridden since the Car inherits from Sprite which in turn inherits from EventDispatcher.

    All it does is return a String statement shown below. Add it as the last method for the Car class.

    
    
    override public function toString ():String
    {
    	return "The car is currently " + _currentState + " with a fuel amount of " + _fuelSupply.toFixed (2) +  " gallon(s).";
    }
    

    So now, whenever you call trace(_car) from Main.as, instead of getting “[object Car]“, you get a statement like “The car is currently off with a fuel amount of 1.00 gallon(s).”

    Let’s go back to Main.as for testing. Be sure to save your work before moving forward.


    Step 13: Stress Testing

    Inside Main’s constructor, right after where you added the ENTER_FRAME event listener. Enter the code below.

    
    
    ///test 0
    _car.turnKeyOff ();
    trace (_car);
    _car.driveForward ();
    trace (_car);
    _car.turnKeyOn ();
    trace (_car);
    

    At this point the Car will perform all six actions without any time lapse. The ENTER_FRAME event has not started yet.

    Next, get inside the update() method just below where _tick is added to _counter and paste the code shown next.

    
    
    _car.update (_tick);
    
    //test 1 after 5 seconds of running the car and
    //only if _initiatedTest1 has a value of false.
    if (_counter >= 5 && ! _initiatedTest1)
    {
    	_initiatedTest1 = true;
    
    	_car.reFuel ();
    	_car.reFuel ();
    	_car.driveForward ();
    	_car.turnKeyOff ();
    	_car.turnKeyOff ();
    	_car.driveForward ();
    	_car.turnKeyOn ();
    	_car.driveForward ();
    	trace (_car);
    }
    
    //test 2 after 11 seconds
    if (_counter >= 11 && ! _initiatedTest2)
    {
    	_initiatedTest2 = true;
    
    	_car.turnKeyOff ();
    	_car.turnKeyOn ();
    	_car.driveForward ();
    	trace (_car);
    }
    
    //test 3 after 30 seconds
    if (_counter >= 30 && ! _initiatedTest3)
    {
    	_initiatedTest3 = true;
    
    	_car.turnKeyOn ();
    	_car.turnKeyOff ();
    	_car.turnKeyOn ();
    	_car.driveForward ();
    	_car.turnKeyOn ();
    	_car.turnKeyOff ();
    	_car.turnKeyOn ();
    	trace (_car);
    }
    
    //test 4 after 35 seconds
    if (_counter >= 35 && ! _initiatedTest4)
    {
    	_initiatedTest4 = true;
    
    	_car.reFuel ();
    	_car.reFuel ();
    	trace (_car);
    
    	_car.turnKeyOff ();
    	_car.driveForward ();
    	_car.turnKeyOff ();
    	_car.turnKeyOff ();
    	_car.turnKeyOn ();
    	trace (_car);
    }
    
    //test 5 after 42 seconds
    if (_counter >= 42 && ! _initiatedTest5)
    {
    	_initiatedTest5 = true;
    
    	_car.driveForward ();
    	trace (_car);
    }
    
    //test 6 after 45 seconds
    if (_counter >= 45 && ! _initiatedTest6)
    {
    	_initiatedTest6 = true;
    
    	_car.turnKeyOn ();
    	_car.turnKeyOn ();
    	_car.driveForward ();
    	trace (_car);
    }
    
    ///stop the car after 60 seconds
    if (_counter >= 60 && ! _finalActions)
    {
    	_finalActions = true;
    
    	trace ('elapsed ' + getTimer () / 1000);
    
    	_car.turnKeyOff ();
    	trace (_car);
    }
    

    I know it’s a lot of code but again, it’s self-explanatory. Run the application and check your output.

    If you get errors, make sure to compare your code with the classes I’ve included with this tutorial.

    Try changing _fuelCapacity in Car and mix-up the methods on some or all of the test sections and run it again. You’ll see that the code is solid and this Procedural FSM is effective. And That’s it! We’re done.

    Wait a minute. Since all is well, why don’t we add the ability to drive backward and turbo? While at it, we might as well add animation and sound. Now, imagine just how bloated the Car class would get if you make it do all the things the car does at the top of page. We’re looking at maybe 2000 lines of code – at least. LOL! I’d probably say, Ya, sure, I can hack that. But the code becomes very fragile and easy to break. So it might be a good idea to use a different technique.

    If the FSM object has simple behavior, by all means, use this technique. But if you have a complex object that might need to add new features in the future. Maybe even add a few more states – well, that’s where the State Pattern comes in.


    Step 14: Introducing the State Pattern

    Say hello to the “big brother” of Procedural FSM. Using this Design Pattern will make your states easy to maintain and make changes to, but the best part – other states can now be added without the risk of ruining the code.

    To apply this pattern, we will again refer to our trusted State Transition Table. See Step 4. The State Pattern consists of three parts. First is the State Interface, this will contain all the actions you see in the State Transition Table. In addition, this State Interface may also contain methods that are shared by all State classes. Second, the State classes that correspond for each state shown in your State Transition Table. And third, the State Machine – which is normally your converted Procedural FSM object (the Car class). When converted, the Car will provide public accessors and modifiers to allow external control from all State classes. The Car will delegate actions to the currently active State.


    Step 15: Beginning the Conversion

    Click “View” and select “Project Manager”. Within “src”, drill down until you see the “fsm” folder. Right-click that and choose “Add > New Interface…” then hit “ENTER”.

    description of image

    Name it “IState”. Interfaces start with “I” for naming convention.

    Once FlashDevelop opens the class, add the code below in it.

    
    
    function turnKeyOff ():void;
    function turnKeyOn ():void;
    function driveForward ():void;
    function reFuel ():void;
    function update ($tick:Number):void;
    function toString ():String;
    

    This IState interface will be implemented by all the State classes. The last function toString() has nothing to do with controlling the Car but all the State classes use it.

    For more info about Interfaces, see AS3 101: Introduction to Interfaces. Let’s start adding the state classes.


    Step 16: The EngineOff Class

    Follow the same procedure when you created the IState Interface but instead, choose “Add new class”.

    description of image

    Name it “EngineOff”. For the interface slot, click add and type “IState”, this should find the IState class from within the same folder. Also, the checkbox for “Generate interface methods implementations” should be selected. Click “OK” to complete.

    The new class comes out half-way finished. It should look very similar to what shows below.

    
    
    package com.activeTuts.fsm
    {
    	public class EngineOff implements IState
    	{
    
    		public function EngineOff()
    		{
    
    		}
    
    		/* INTERFACE com.activeTuts.fsm.IState */
    
    		public function turnKeyOff():void
    		{
    
    		}
    
    		public function turnKeyOn():void
    		{
    
    		}
    
    		public function driveForward():void
    		{
    
    		}
    
    		public function reFuel():void
    		{
    
    		}
    
    		public function update($tick:Number):void
    		{
    
    		}
    
    		public function toString():String
    		{
    
    		}
    
    	}
    
    }
    

    These state classes won’t need to extend Sprite since all Media assets (second part) will be added and controlled via the car. The states will be instantiated through the Car class passing itself as reference. A two-way composition structure will be used to allow communication between the Car and the state classes.


    Step 17: Finishing Our EngineOff Class

    Change the constructor method to match the code below.

    
    
    private var _car:Car;
    
    public function EngineOff ($car:Car)
    {
    	_car = $car;
    }
    

    I’ve included the _car variable above the modified constructor. Now we can control the Car class from within this state.

    Let’s move on to the interface method implementations.

    Get inside the turnKeyOff() method. Check your State Transition Table to see what happens here. Next, compare that with the procedural turnKeyOff() method inside the Car class. Remember, we still have the Car class in Procedural FSM. Once you see the match. Copy the action for the ENGINE_OFF state into the empty method. The turnKeyOff() method should reflect what you see below.

    
    
    public function turnKeyOff ():void
    {
    	_car.print ("The car's already off, you can't turn the key counter-clockwise any further...");
    }
    

    The trace() statement has been replaced by print() which we’ll add to the Car class later.

    Now go inside the turnKeyOn() method and add the code listed next.

    
    
    	_car.print ("Turning the car on...the engine is now running!");
    	_car.changeState (_car.getEngineOnState ());
    

    Check it against you State Transition Table and procedural turnKeyOn() method for the ENGINE_OFF state to see if it’s the same. The changeState() method is delegated back to the car passing in the retrieved state it needs to change to.

    The rest of the methods are processed the same way. Copy the code below and replace the empty methods with it.

    
    
    public function driveForward ():void
    {
    	_car.print ("click, changing the gear to drive doesn't do anything...the car is not running, returning the gear to park...");
    }
    
    public function reFuel ():void
    {
    	if (_car.hasFullTank () == false)
    	{
    		_car.print ("getting out of the car and adding " + Number (_car.refillWithFuel ()).toFixed (2) + " gallon(s) of fuel.");
    	}
    }
    
    public function update ($tick:Number):void { }
    
    public function toString ():String
    {
    	return 'off';
    }
    

    The driveForward() method does the same as the procedural driveForward() methods with _currentState set as ENGINE_OFF

    reFuel() asks the car to see if the tank is not full. If not, the car will then refill with fuel. You’ll see how those two methods work when we change the Car class later.

    The update() method remains empty since the car won’t be running.

    toString() works the same as the car’s toString() method.

    This completes the EngineOff class.

    Before creating the rest of the other state classes, let’s modify the Car class and convert it into its own State Machine.


    Step 18: The Car State Machine

    Important: Create a duplicate Car class before following the procedure below. A text copy would suffice but make sure to save it as reference for later.

    Instead of going through the changes item by item, just copy the code below then paste and replace the content of your Car class with it.

    
    
    package  com.activeTuts.fsm
    {
    	import flash.display.Sprite;
    	import flash.events.Event;
    
    	public class Car extends Sprite
    	{
    		///CAR STATES
    		//engine off state
    		//engine on state
    		//drive state
    		//no gas state
    
    		public static const ONE_SIXTH_SECONDS:Number = 1 / 6; //6 times per second
    
    		public static const IDLE_FUEL_CONSUMPTION:Number = .0055;
    		public static const DRIVE_FUEL_CONSUMPTION:Number = .011;
    
    		private var _engineOffState:IState;
    		private var _engineOnState:IState;
    		private var _engineDriveForwardState:IState;
    		private var _engineOutOfFuelState:IState;
    
    		private var _fuelCapacity:Number = 1;
    		private var _fuelSupply:Number = _fuelCapacity; //starting on a full tank (in gallons)
    
    		private var _engineTimer:Number = 0;
    
    		private var _currentState:IState;
    
    		public function Car ()
    		{
    			init ();
    		}
    
    		private function init ():void
    		{
    			initializeStates ();
    		}
    
    		private function initializeStates ():void
    		{
    			_engineOffState = new EngineOff (this);
    			_engineOnState = new EngineOn (this);
    			_engineDriveForwardState = new EngineDriveForward (this);
    			_engineOutOfFuelState = new EngineOutOfFuel (this);
    
    			_currentState = _engineOffState;//default state
    		}
    
    		public function update ($tick:Number):void
    		{
    			_currentState.update ($tick);
    		}
    
    		///car functions
    		public function turnKeyOn (e:Event = null):void
    		{
    			_currentState.turnKeyOn ();
    		}
    
    		public function turnKeyOff (e:Event = null):void
    		{
    			_currentState.turnKeyOff ();
    		}
    
    		public function driveForward (e:Event = null):void
    		{
    			_currentState.driveForward ();
    		}
    
            public function reFuel (e:Event = null):void
    		{
    			_currentState.reFuel ();
    		}
    
    		public function consumeFuel ($consumption:Number):void
    		{
    
    			if ((_fuelSupply -= $consumption) <= 0)
    			{
    				_fuelSupply = 0;
    				print ("the engine has stopped, no more fuel to run...");
    
    				changeState (_engineOutOfFuelState);
    			}
    		}
    
    		public function refillWithFuel ():Number
    		{
    			var neededSupply:Number = _fuelCapacity - _fuelSupply;
    			_fuelSupply += neededSupply;
    			return neededSupply;
    		}
    
    		public function hasFullTank ():Boolean
    		{
    			var fullTank:Boolean = _fuelCapacity == _fuelSupply ? true : false;
    			if (fullTank) print ("no need to refuel right now, the tank is full...");
    			return fullTank;
    		}
    
    		public function getEngineOffState ():IState { return _engineOffState; } //explicit, you know you're calling a method
    
    		public function getEngineOnState ():IState { return _engineOnState; }
    
    		public function getEngineOutOfFuelState ():IState { return _engineOutOfFuelState; }
    
    		public function getEngineDriveForwardState ():IState { return _engineDriveForwardState; }
    
    		public function changeState ($state:IState):void
    		{
    			_currentState = $state;
    		}
    
    		public function get engineTimer ():Number { return _engineTimer; } //implicit, as if you're accessing a public variable
    
    		public function set engineTimer ($value:Number):void { _engineTimer = $value; }		
    
    		public function print ($text:String):void
    		{
    			trace ($text);
    		}
    
    		override public function toString ():String
    		{
    			return 'The car is currently ' + _currentState + ' with a fuel amount of ' + _fuelSupply +  ' gallon(s).';
    		}
    	}
    }
    

    Let’s go over the changes.

    Starting at variable definition. You’ll notice that the four states have changed type to IState and are no longer static constants.

    Next, the constructor now calls init() which in turn calls initializeState(). All the state classes are instantiated through that method.

    Then comes the easy part, no more switch statements. The car just delegates the actions to the current state. See turnKeyOff() down to reFuel()

    The consumeFuel() method had to become public access for EngineOn and EngineDriveForward.

    And then the two methods we used in EngineOff’s reFuel() method – hasFullTank() and refillWithFuel().

    Below them are the explicit getters that provide access for all four states. It may seem like it’s weird protocol but it’s just encapsulation at work.

    The changeState() does exactly what it says, it changes the _currentState.

    Again, following the strict rule of OOP, the _engineTimer property can be accessed and modified through these two methods: get engineTimer() and set engineTimer().

    print() for now will just pass the String parameter to a trace() statement. And then the toString() method.


    Step 19: Creating the Other Three States

    To simplify creation of the three other classes, get inside the Car class from within the initialize() method. Place your cursor inside the “EngineOn” word and press “CTRL + SHIFT + 1″ to generate a prompt. Select “Create new class” and hit “ENTER”.

    Match the information as shown in the image below then click “OK”.

    description of image

    This is similar to Step 16 when you created the EngineOff class. Only this time, we used FD’s shortcut keys. Also, you’ll notice a refence to the car object in the constructor which was passed in at instantiation. Don’t forget to add that “$” sign to the car parameter for your constructor and the only class variable _car on top.

    Compare it with the code below.

    
    
    package com.activeTuts.fsm
    {
    	public class EngineOn implements IState
    	{
    		private var _car:Car;
    
    		public function EngineOn($car:Car)
    		{
    			_car = $car;
    		}
    
    		/* INTERFACE com.activeTuts.fsm.IState */
    
    		public function turnKeyOff ():void
    		{
    
    		}
    
    		public function turnKeyOn ():void
    		{
    
    		}
    
    		public function driveForward ():void
    		{
    
    		}
    
    		public function reFuel ():void
    		{
    
    		}
    
    		public function update ($tick:Number):void
    		{ 
    
    		}
    
    		public function toString ():String
    		{
    
    		}
    
    	}
    
    }
    

    Now go back inside the initialize() method in Car and repeat the process for the last two remaining state classes.


    Step 20: Completing the EngineOn Class

    Do you think you can piece it together using the Car.txt (duplicate) and State Transition Table?

    Give it a shot, just follow Step 17 and you’ll do great. Just remember that you’re working on action results for ENGINE_ON now.

    Excellent! When you’re done, compare your code with the classes inside the folder “StatePatternPartial1″ included with the source download.


    Step 21: Final Testing

    Once you finish work with all your state classes, go back to Main.as and run your application.

    Hopefully everything went well and you didn’t get any errors. Information should start printing out of your output panel.

    We’ll end the first part of the tutorial here. For the second part, we’ll start by adding the two other states “EngineDriveReallyFast” and “EngineDriveBackward”. Then we’ll add controls for animation and sound proving how easy it is to modify and scale.


    Conclusion

    Of all the design patterns I’ve played with, this one is by far the most important (for me), especially in the realm of game design. You’ll see why when you start using it to build your next game object. Why don’t you try creating the pistol I mentioned at the beginning of this tutorial. You’ll enjoy creating it! Just remember to start small. Always build it from Procedural FSM then convert it to the State Pattern.

    Here are the steps:

    1. Sketch up the State Transition Table for your Object.
    2. Create your Procedural FSM Object.
    3. Once Procedural FSM works, if you need to add a lot more feature and/or states, convert it to the State Pattern.
    4. Build your IState Interface first.
    5. Create the first/default State class (Consult State Transition Table and Procedural FSM actions).
    6. Duplicate a copy of your Procedural FSM Object, then allow public access to all properties the State classes need to control.
    7. Create the rest of the State classes.
    8. Add features/states as per your requirements. These usually present themselves while you’re working on your State actions.

    See you in the second part!

    As always, for any comments, suggestions, or concerns, please post a note in the comments section.

    Thanks for reading!


  9. James Tyner says:
    September 16, 2011 at 12:05 am

    In the first part of this members-only tutorial, you built the basic structure of a Flash card-matching game, using Flickr to get its images. Now you’ll complete the game, adding multiple levels and a full interface.

    Become a Premium member to follow this awesome tutorial, as well as hundreds of other advanced tutorials and screencasts.


    Preview

    Here’s what you’ll create by the end of this tutorial:


    Active Premium Membership

    Activetuts+ Premium Membership

    We run a Premium membership system which costs $9 a month (or $22 for 3 months!) which periodically gives members access to extra tutorials, like this one! You’ll also get access to Psd Premium, Vector Premium, Audio Premium, Net Premium, Ae Premium, Cg Premium and Photo Premium too. If you’re a Premium member, you can log in and download the tutorial. If you’re not a member, you can of course join today!

    Also, don’t forget to follow @envatoactive on twitter and grab the Activetuts+ RSS Feed to stay up to date with the latest tutorials and articles.


  10. Dru Kepple says:
    September 16, 2011 at 12:31 am

    It’s time for another debugging Quick Tip. We’ll continue our focus on specific (and common) errors that tend to stymie less-experienced ActionScripters. In this case, we’ll cover Error #1063, the argument count mismatch error.


    Step 1: Being Bad

    First, let’s create a situation where the error occurs. Open up a new Flash document (assuming you’re following along with Flash Pro CS3+, otherwise this sample is easily adapted to a Flex project). Open the Script Editor and enter the following code:

    
    
    import flash.events.MouseEvent;
    
    function onClick():void {
        trace("click.");
    }
    
    stage.addEventListener(MouseEvent.CLICK, onClick);
    

    You can probably spot the problem already; if you’ve spent any amount of time writing ActionScript 3 you’ll have found yourself writing event handlers. If not, don’t feel bad — we’ll go over it all in due course.

    If you run the Flash file as is, and then click on the stage, you’ll produce the following run-time error message:

    
    
    ArgumentError: Error #1063: Argument count mismatch on Untitled_fla::MainTimeline/onClick(). Expected 0, got 1.
    

    And we never get to the trace statement that should have run after clicking.


    Step 2: Breaking It Down

    So what’s going on? In this case, Adobe’s verbiage for the error is actually not so bad, and if you’ve gotten used to parsing a run-time error message, its meaning might be pretty clear. But not everyone is as smart as you, so here’s the breakdown for everyone else.

    ArgumentError — This is someone inconsequential information, but it shows the specific Error class that was thrown. We’ve got something that’s not as general as a simple Error, and we’ve entered a specific categorization of error associated with arguments (to functions and methods).

    Error #1063 — Here we’re just giving the formal error number, like all good run-time errors. You can use this code to more easily locate it in Adobe’s run-time error documentation.

    Argument count mismatch… — In more proletarian terms, there were the wrong number of arguments sent to a function. Which function? It’s…

    …on Untitled_fla::MainTimeline/onClick(). — This simply identifies the function that received the wrong number of arguments.

    Expected 0, got 1. — We get a bit of extra information in this error description. This details the count mismatch. This phrase will change according to the nature of the specific error, but in our case it’s saying that the function was written without any arguments in the signature, but a single argument got sent to it anyway.

    Flash likes its ducks in a row. So, it notices this discrepancy and decides to throw a tantrum error, because it would rather you (the developer) figured out what went wrong than that you simply ignored the problem. This is good, because if the count mismatch went the other way (expected 1, got 0), then we’d be stuck without an argument for a required parameter, and the function would do Dog knows what.


    Step 3: The Root of the Problem

    The nature of the error should be clear at this point, but you may still be wondering why it occurred at all. Where did that superfluous argument come from?

    The argument isn’t exactly superfluous. It’s expected, actually, since we’ve hooked up our function to be an event listener. The event system in Flash has the notion of an event object that encapsulates aspects of the event that occurred. This object gets passed to the listener function as the sole argument. So, we expected 0 because we wrote our function without any parameters, but we got 1 because the event dispatcher sent along an event object.

    Now you may be wondering why the compiler didn’t catch this error. It’s true: if you wrote this:

    
    
    function sayClick():void {
        trace("click.");
    }
    sayClick(42);
    

    Then the SWF won’t even compile, because you’ll get this error:

    
    
    1137: Incorrect number of arguments.  Expected no more than 0.
    

    The difference is that in the latter example, we have actual code that calls the function with the wrong number of arguments. That is, we wrote the line down that calls the function incorrectly. The compiler can look at the line that defines the function, and the line that calls the function, and compare them for discrepancies, and sound the alarm when they occur.

    Bat Signal
    Image by Alan / Falcon

    However, in the original example, there is no line of code written down that literally calls the function by name. Instead, the function is called by reference. When we add the event listener, we pass in the function, and at that point it’s a variable, not a function call. This reference gets stored by the event dispatcher, and then executed dynamically when the event occurs (that’s a real high-level overview of how the event system works, but we don’t have time to go deeper). So, the line of code that ultimately calls the error-causing function is a rather generic line of code that uses indirection to get the job done, and therefore something much harder for the compiler to catch.

    (In my opinion, Adobe could at least register the addEventListener line at compile time, and go looking for the function reference by name. If it finds a match, it could check the function signature for a proper event argument, and produce errors accordingly. It still couldn’t be done in a foolproof way, but it might go a long way to catching these errors before actually running the SWF.

    The main point, though, is that this run-time error has a compile-time counterpart, but that the run-time error occurs when the function is called by reference and not directly by name.


    Step 4: Fixing the Hole

    The rain is getting in when we call the function by reference, and have a discrepancy in the number of arguments. We generally have two options: we can modify the call, or modify the function’s arguments. In this particular example, we can’t modify the call, as that happens inside EventDispatcher, code to which we don’t have access. That leaves us with modifying the arguments.

    This, again, has two options. First, we can simply add the argument. This lines up the number of arguments and from here on out, everything will be copacetic. We don’t need to use the argument, we just need to have the function “catch” it when it’s called.

    
    
    function onClick(e:MouseEvent):void {
    

    The second option is to, again, add the argument (no way around that, I’m afraid). However, if you originally wrote the function as a regular function and not an event listener, and are calling it from elsewhere in your code without arguments, you may appreciate this variation. Make the argument optional, and default it to null:

    
    
    function onClick(e:MouseEvent=null):void {
    

    This will work well with the event system: it gets sent an event object and can catch it. It also works well with your existing code; if no argument is sent, the parameter default is used and the function proceeds.


    Step 5: Callbacks

    Note that this error is not limited to event listeners, although that’s probably the most common context where you’ll experience it. Ultimately it’s the using of functions stored in variables, as opposed to called by name, that leads to the error. This is how the event system works. We can rework the original example to produce more or less the same error, only without the click:

    
    
    function sayMyName(name:String):void {
        trace("Hello, " + name);
    }
    
    var funcRef:Function = sayMyName;
    
    funcRef();
    

    Again, we get past the compiler error because we have a layer of indirection between the function definition and the function call. Thus, we get the run-time error (expected 1, got 0).

    It’s not always this cut and dry, though. If you utilize callbacks in your code, you might fall prey to error 1063. Callbacks are sort of like event listeners, only there is no formal, built-in mechanism for implementing them. They’re basically just functions you pass around by reference, which are stored (either temporarily or long-term) by some other process, which then calls the callback function at the appropriate time.

    Tweening engines typically implement these. Some go for a more formal event-driven system, but TweenLite, for example, utilizes callbacks for receiving notifications about the tween progress. This line:

    
    
    TweenLite.to(someClip, 1, {onComplete:tweenFinished, onCompleteParams:[42, "answer"]});
    

    …would call a function named tweenFinished at the end of the tween, passing in two parameters to the function. This technique is ultimately more flexible then events, as you are not limited to just the single event object as a parameter. But it does yield itself to similar vulnerabilities to error 1063 due to the nature of passing functions around by reference.


    That Is All

    That wraps up another Debugging Quick Tip. Thanks for reading, and I hope you learned something along the way!


Leave a Reply

Click here to cancel reply.

search search search search search
Find an Article
Categories
  • Flash Video Training
  • Hints and Tips
  • Recommended
Please Support Our Sponsors
Recent Posts
  • Workshop Coding Challenge: Fix This Breakout Game
  • Enable the Latest AIR SDK in Flash Professional CS5.5+
  • Quick Tip: Versioning Your Files With Dropbox (via Webdesigntuts+)
  • Workshop: Nuclear Outrun – Critique
  • Understanding Variables, Arrays, Loops, and Null: The Post-it Note Analogy
Tag Cloud
2011 ActionScript Active Activetuts+ Adobe animation Basic Basix Best Build Button Character 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+ Tween 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
May 2012
M T W T F S S
« Apr    
 123456
78910111213
14151617181920
21222324252627
28293031  
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

  • 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