Advertisement
Games

Advanced Character Customization for Flash Games

by

In this tutorial, we'll delve into Flash game character customization. The result can be used to provide players with the ability to create a unique character, beyond the basic dress-up options of most games.

We found this awesome author thanks to FlashGameLicense.com, the place to buy and sell Flash games!

We'll learn how to let the user add custom colors to different parts of our character, how to add hand-drawn designs to the character's clothing, and how to modify a basic walking animation that uses the player's changes.


Final Result Preview

This is what you'll have built by the end of the tutorial:

Fill the areas of the character's clothing with solid colors, add detail with the pencil, then hit "play" and press left and right to see him walk!


Step 1: Setting Up Our Flash Movie

Create a new AS3 Flash Document. Go into the properties panel and make sure that all of the settings are the same as the image below:


Step 2: Setting Up Our Main Class

Next create a new .as file called CustomCharacter.as inside the directory of our project. This will be our main class. Enter CustomCharacter into the Publish settings as the "Main Class".
Make sure that your CustomCharacter class is as below.

package 
{
	import flash.display.Sprite;
	import flash.display.BitmapData
	import flash.net.FileReference
	import flash.display.Loader
	import flash.display.Bitmap
	import flash.display.MovieClip
	import fl.controls.ColorPicker
	import flash.events.Event
	import flash.events.MouseEvent

	
	public class  CustomCharacter extends Sprite
	{
		
	
		public function CustomCharacter():void {
		
		
		
		}
		
		
	}
	
	
	
}

(Check out this quick introduction to the document class if you're not sure what we're doing in this step.)


Step 3: Creating Our Main Character

Now we will begin by drawing our main character. In this tutorial, it is important that we make sure we have every body part in a separate MovieClip. By doing this, we can base our walking animation on Tweens which will speed up the animation process. Our character will be made up of the following objects: a head, hair, a shirt, two legs, and two arms. You can find the main character used in this tutorial in the source FLA (download link is at the top of the tutorial).

For now, to encourage the player to customize the character, we'll limit the colors of the body parts of the character to grey with black outlines. Select the entire body, push F8 to turn it into a single MovieClip and call it Player. Make sure that you set the registration point of each body part to the upper left corner. Now click on the new Player movieclip on the stage and set the instance name to player.

There you have it, we've just created our Player character!


Step 4: Creating a ColorPicker

To begin, we need to add the ColorPicker component to our library. Go into the components panel by going to Window > Components. Find the ColorPicker class and drag it into the library panel.

Next we need to do all of the ActionScript work. Here is what our CustomCharacter class will look like after our new changes.

package 
{
	import flash.display.Sprite;
	import flash.display.BitmapData
	import flash.events.Event;
	import flash.net.FileReference
	import flash.display.Loader
	import flash.display.Bitmap
	import flash.display.MovieClip
	import fl.controls.ColorPicker	
	import flash.events.MouseEvent
	
	public class  CustomCharacter extends Sprite
	{
		var myColorPicker:ColorPicker = new ColorPicker();
	
		public function CustomCharacter():void {
			
		myColorPicker.editable = true;
		myColorPicker.visible = false;
		addChild(myColorPicker);
		
		player.addEventListener(MouseEvent.CLICK, showPicker)
		myColorPicker.addEventListener(Event.CHANGE, colorChanged)
		
		}
		
		private function colorChanged(e:Event):void 
		{
			myColorPicker.visible = false;
		}
		
		private function showPicker(e:MouseEvent):void 
		{
			myColorPicker.visible = !myColorPicker.visible 
			myColorPicker.move(stage.mouseX,stage.mouseY)
			
		}
		
		
		
		
	}
	
	
	
}

Let's go through this step by step, starting with the constructor function. First, we are creating a new var called myColorPicker. We are then telling it that it is an instance of the ColorPicker class by calling = new ColorPicker(). Next we are telling our ColorPicker to be changeable and invisible, so we can make it show up when we click on the player. Then, we add the ColorPicker class to the stage, although it isn't visible.

We also add two event listeners. One for when you click on the player, which toggles the visibility of the ColorPicker and moves it to the mouse location upon click, and the second one to check to see when the user has selected a new color, so that we can make the ColorPicker invisible again!


Step 5: Distinguishing Between Body Parts

Unfortunately, we can't just use the ColorPicker and make it change an object's color. First, we need for the ColorPicker to distinguish which object you are clicking on, so that it can determine which object to change. This requires using one of AS3's powerful MouseEvent features.

Inside the showPicker function, we can just use e.target to target the MovieClip that is really being clicked on. We can bring the alpha of the clicked object down to confirm which object we are dealing with. Just add the code below to the showPicker() function.

e.target.alpha -= .5

Step 6: Preparing for Color!

We're almost ready to color our objects. Before we start, we need to make sure that we can keep the outlines on our body parts. To do this, we need to identify the area that needs a color change. We are going to have to go inside the MovieClip for every body part, and select the gray fill area inside the outline.

Next, push F8 to create a new MovieClip of this gray fill and call it "_____Color" (so for the arm movieclip we will call it ArmColor). Finally, set the instance name of each of these ____Color objects to color. Now every body part should have a color MovieClip inside it.


Step 7: Los Colores (The Colors)

We are finally adding coloring to our application. Here is what your project should look like at the end of this step:

package 
{
	import flash.display.Sprite;
	import flash.display.BitmapData
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.net.FileReference
	import flash.display.Loader
	import flash.display.Bitmap
	import flash.display.MovieClip
	import fl.controls.ColorPicker	
	import flash.events.MouseEvent
	
	public class CustomCharacter extends Sprite
	{
		var myColorPicker:ColorPicker = new ColorPicker();
		var myChangedObject:MovieClip;
		
		public function CustomCharacter():void {
		
		
		myColorPicker.editable = true;
		myColorPicker.visible = false;
		addChild(myColorPicker);
		
		player.addEventListener(MouseEvent.CLICK, showPicker)
		myColorPicker.addEventListener(Event.CHANGE, colorChanged)
		
		}
		
		private function colorChanged(e:Event):void 
		{
			myColorPicker.visible = false;
			var myChange:ColorTransform = new ColorTransform();
			myChange.color = new uint("0x" + e.target.hexValue)
			myChangedObject.transform.colorTransform = myChange
		}
		
		private function showPicker(e:MouseEvent):void 
		{
			if (e.target.name == "color") {
				myColorPicker.visible = !myColorPicker.visible 
				myColorPicker.move(stage.mouseX, stage.mouseY)
				myChangedObject = MovieClip(e.target)
				myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
			}
			
		}
		
		
		
		
	}
	
	
	
}

Application Screenshot

Alright! Let's go through this step by step. To begin with, we are creating a new MovieClip variable, myChangedObject, to be accessed by our program. This is so our showPicker() function can tell our colorChanged() function which MovieClip was last clicked on.

Seeing as that's out of the way, let's look at our showPicker() function. As you can see, we added a little checker to see if the clicked on object's name is "color". This is just a check to see whether the user has actually clicked on the player's outline, shoes, or anything else that isn't meant to be changed.

Next we are changing our new myChangedObject variable to be equal to the clicked-on object, e.target, so that our colorChanged() function can make the final changes. Finally, we are telling our ColorPicker (myColorPicker)
to have the previously selected color preselected. If there is none, then it will default to black.

myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)

Lets analyze this little bit of code. First of all, it is important to know that to have a preselected color, the ColorPicker class has a .selectedColor variable. This is a number that can receive a 6-digit int (0xRRGGBB). In the second part, we are converting the data in the parentheses to a uint to be passed onto the ColorPicker.

Here's the key, we are essentially going inside our selected MovieClip myChangedObject, going into its transform section (where our data is stored), going into the colorTransform data of the transform data, and pulling out the color variable which holds our RGB code (which we then pass as the selected color of the color picker). Think about it like a directory:

myChangedObject/Transform Data/Color Transform Data/Color Data (RGB)

We're still not done yet! Next let's look at our colorChanged() function. Here, we are creating a new instance of the ColorTransform class. We are then setting the color variable inside the ColorTransform class to the color that the user has selected with the color picker.

However, we need to add a "0x" to the ColorPicker's chosen color (e.target.hexValue) to form the complete variable that we can pass on to our ColorTransform. That's because hexValue gives colors in "RRGGBB" string format, and we need them in 0xRRGGBB integer format. Like before, we are converting all of the added data to a new uint() that the ColorTransform can recognize.

FINALLY, we are going back into: myChangedObject.transform.colorTransform except this time, we are ACTUALLY changing the colorTransform variable to the new ColorTransform variable we have just created.

Whew, that was confusing but now that that part is over, we can start adding new features to our program.


Step 8: Switching Between Pencil and Paint Bucket

Now that we have a functional coloring app, let's move on to add some more functionality.

Next, we are going to try to make the program draw directly onto the player's body parts, so that the user can draw some cool designs for his character. As you can see above, I've put together a panel with two tools. Firstly, we have a drawing pencil and next we a paint bucket tool. The purpose of this tutorial is not to put together the UI, but I HAVE included them in the source. You can dissect the graphics if you want to learn how they were made.

Also, this is sort of an extension from this tutorial by Carlos Yanez, which does a great job of explaining how to create a drawing application.

Just as in that tutorial, I have a interface that consists of two paint bucket and two pencil images. One is gray and the other is in color. The gray one will make the colorful image visible to show that the tool has been activated.

Once one tool is activated, the other will be disabled. In this step, we are only working on switching between the tools. During the following steps, we will cover how to get the pencil tool to work. Here is what our code should look like:

package 
{
	import flash.display.Sprite;
	import flash.display.BitmapData
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.net.FileReference
	import flash.display.Loader
	import flash.display.Bitmap
	import flash.display.MovieClip
	import fl.controls.ColorPicker	
	import flash.events.MouseEvent
	
	public class  CustomCharacter extends Sprite
	{
		var myColorPicker:ColorPicker = new ColorPicker();
		var myChangedObject:MovieClip;
		
		public function CustomCharacter():void {
		
		
		myColorPicker.editable = true;
		myColorPicker.visible = false;
		addChild(myColorPicker);
		
		
		tools.bucket.visible = false;
		tools.pencil.visible = false;
		
		tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
		tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
		
		
		}
		
		private function enablePencil(e:MouseEvent):void 
		{
			
		tools.bucket.visible = false;
		tools.pencil.visible = true;
		player.removeEventListener(MouseEvent.CLICK, showPicker)
		myColorPicker.removeEventListener(Event.CHANGE, colorChanged)
		
		}
		
		private function enableBucket(e:MouseEvent):void 
		{
		
		tools.bucket.visible = true;
		tools.pencil.visible = false;
		player.addEventListener(MouseEvent.CLICK, showPicker)
		myColorPicker.addEventListener(Event.CHANGE, colorChanged)
		
		
		}
		
		private function colorChanged(e:Event):void 
		{
			myColorPicker.visible = false;
			var myChange:ColorTransform = new ColorTransform();
			myChange.color = new uint("0x" + e.target.hexValue)
			myChangedObject.transform.colorTransform = myChange
		}
		
		private function showPicker(e:MouseEvent):void 
		{
			if (e.target.name == "color") {
				myColorPicker.visible = !myColorPicker.visible 
				myColorPicker.move(stage.mouseX, stage.mouseY)
				myChangedObject = MovieClip(e.target)
				myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)

			}
			
		}
		
		
		
		
	}
	
	
	
}

First, you can see that we have taken out the showPicker and colorChanged event listeners, and they are now only to be
added when we choose the paint bucket options. Instead, we have added two event listeners for each button, which link to two functions that activate the tool we have clicked on. The functions add their own event listeners and remove the event listeners from the other tool. They also make the right interface items visible and invisible.

Our new application


Step 9: Using a Color Picker For Pencil

We have setup the interface, but a question remains. How can we choose what color to draw with for the pencil tool? The answer is simple. We can just reposition our color picker to be next to the pencil tool. It's quite simple too. Just add this to the end of the enablePencil() function:

	myColorPicker.visible = true
	myColorPicker.move(515, 20);	//or whatever coordinates suit your layout

Just to make sure that the player doesn't use the ColorPicker when selecting the bucket tool, we can just add this to the enableBucket() function:

	myColorPicker.visible = false

Step 10: An Array of Body Parts

We are getting closer to being able to draw onto our character, but we still have some work to do. Soon, we are going to start masking our drawings to movie clips inside the character, so that they stay within the outline of the character. To do this, first we need to create a list of objects that need to be masked. We can do this in the form of an array.

Unlike before, we are going to have to give each body part an instance name, so go back into the player movie clip, and select each object one by one. Give each object a name ("arm1", "leg2", "hair", etc.). When you have finished that, create an array in the CustomCharacter() constructor, like so:

	var drawableParts:Array = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair];

Sadly, that doesn't work as planned.

TypeError: Error #1009: Cannot access a property or method of a null object reference.
	at CustomCharacter()

This is because we are trying to reference the player movieclip before it is constructed. To solve this, we need to reference it in the constructor, too.

Basically, we are splitting up the variable into two parts. The first part is before the constructor when we create the array, so that it'll be accessible throughout the class. The second is INSIDE the constructor when we can assign it a value.

Here is a snippet of our class:

public class  CustomCharacter extends Sprite
{
	var myColorPicker:ColorPicker = new ColorPicker();
	var myChangedObject:MovieClip;
	var bucket:Boolean = false
	var drawableParts:Array 
	
	public function CustomCharacter():void {
	
		drawableParts = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair]

		myColorPicker.editable = true;
		myColorPicker.visible = false;
		addChild(myColorPicker);
		
		
		tools.bucket.visible = false;
		tools.pencil.visible = false;
		
		tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
		tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
	}

Step 11: Creating a Canvas to Draw On

To be able to draw into an object, we need to use the Shape class. First, add the import statement to the other ones
at the beginning of our Main class.

	import flash.display.Shape;

This is what you need to add to the bottom of your CustomCharacter() constructor function:

for (var i:int = 0; i < drawableParts.length;i++ ) {
	var myShape:Shape = new Shape()
	
	myShape.graphics.lineStyle(1,0x330000);
	myShape.graphics.beginFill(0x3312FF,0.5);
	myShape.graphics.drawRect(0,0,drawableParts[i].width * 3,drawableParts[i].height * 3);
	myShape.graphics.endFill();
	
	myShape.name = "shapes"
	
	drawableParts[i].addChild(myShape)
}

Here's a quick explanation of what we are doing. We are basically creating a for loop that triggers once for each of the items in our array. In the loop, we create a new instance of the Shape class.

The next four lines are just for debug testing, sort of like Box2D debug draw. Basically it is displaying purple boxes around the character's body parts. The only thing to keep in mind is that we are multiplying the width and height of each body part by 3 to get the width and height of our purple testing box, so that we know each of these "canvases" will be big enough to draw on. Next we assign the name "shapes" to each Shape created, and add it into the current item of the drawableParts array.


Step 11: Masking our Shapes

To start off, we will need to give our shapes a surface to be masked too. We can't just link them to our body part MovieClip, because then those will turn invisible. This is what we can do instead.

Go into the hair MovieClip. Right-click on our color MovieClip and click "Copy". Next, right-click on some empty space inside our hair MovieClip and click "Paste in Place". Now go into the properties of our new MovieClip and set the instance name to maskclip. Now go back to our player MovieClip and repeat this for every object.

Next we can add this code to the end of our for loop:

	myShape.mask = drawableParts[i].maskclip

Test the Movie again and just like magic, our player turns purple, because only the area of the player that is shaded in is showing our debug boxes. This means that our drawings will stay on the surface that we are drawing on.


Step 12: Accessing Our Canvas

Now the comes question: "How do I access the canvas myShape of each body part?" Unfortunately, the answer is not so simple. However, I can walk you through it step by step. This snippet will link us directly back to our myShape if we insert it in a MouseEvent. Why? Well just keep on reading..

e.target.parent.getChildByName("shapes")

Let's go through this step by step. This process is kind of like a mouse (yes a real one) trying to find his cheese (our canvas) because
we need to go through a bunch of twists and turns to find what we are looking for.

  • First, we are going to the target of the MouseEvent. This can be the object that the mouse clicked, released, moved over, etc.
  • Next we are going to the parent of that object. This is bound to be a body part MovieClip (such as the arm) because the only clickable objects are either the outline or the filling of the Player (we will make sure it is the filling later).
  • Now that we are at the body part MovieClip, we can use getChildByName("Object Name Here") to access the object with the given name.

Because we previously named all of our Shape objects as shapes, calling getChildByName("shapes") will give us access to them.


Step 13: Black and White Coloring

Now we can start to actually draw on the player in black and white.

This is what our Main class should look like at the end of the tutorial. I've added comments to all of the changes I've made.

package 
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.BitmapData
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.net.FileReference
	import flash.display.Loader
	import flash.display.Bitmap
	import flash.display.MovieClip
	import fl.controls.ColorPicker	
	import flash.events.MouseEvent
	
	public class  CustomCharacter extends Sprite
	{
		var myColorPicker:ColorPicker = new ColorPicker();
		var myChangedObject:MovieClip;
		var bucket:Boolean = false
		var drawableParts:Array 
		
		//A boolean to check to see if the mouse is drawing
		var drawing:Boolean = false
		
		public function CustomCharacter():void {
			drawableParts = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair]
			myColorPicker.editable = true;
			myColorPicker.visible = false;
			addChild(myColorPicker);
			
			
			tools.bucket.visible = false;
			tools.pencil.visible = false;
			
			tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
			tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
			for (var i:int = 0; i < drawableParts.length;i++ ) {
				var myShape:Shape = new Shape()
				
				myShape.name = "shapes"
				
				drawableParts[i].addChild(myShape)
				myShape.mask = drawableParts[i].maskclip
			}
		}
		
		
		private function enablePencil(e:MouseEvent):void 
		{
			tools.bucket.visible = false;
			tools.pencil.visible = true;
			player.removeEventListener(MouseEvent.CLICK, showPicker)
			
			//Removing eventListener placed by our bucket tool
			myColorPicker.removeEventListener(Event.CHANGE, colorChanged)
			
			//Checks to see when our ColorPicker changes color while Pencil is selected
			myColorPicker.addEventListener(Event.CHANGE, colorChangedPencil)
			
			//Checks to see if the mouse is down, up, or moving
			player.addEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
			player.addEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
			player.addEventListener(MouseEvent.MOUSE_MOVE, moveDrawOnPlayer)

			myColorPicker.visible = true
			myColorPicker.move(515, 20);
		}
		
		//Function to check for movement of the mouse, while drawing
		private function moveDrawOnPlayer(e:MouseEvent):void 
		{
			//If our mouse is hovering over the filling of the player and if we are indeed drawing
			if (e.target.name == "color" && drawing) {
					//Draw a line from the graphical section of our shape movieclip to the location of the mouse
					//We need to use ourCanvas.mouseX or mouseY because that gives us local coordinates of the mouse that our canvas can use
					e.target.parent.getChildByName("shapes").graphics.lineTo(e.target.parent.getChildByName("shapes").mouseX,e.target.parent.getChildByName("shapes").mouseY);
			}

		}
		
		private function dontDrawOnPlayer(e:MouseEvent):void 
		{
			//When you release the mouse, stop drawing
			drawing = false;
			
		}

		//new function
		private function drawOnPlayer(e:MouseEvent):void 
		{
			//When you click, start drawing
			drawing = true;
			
			//If you are clicking on a "color" MovieClip
			if (e.target.name == "color" ) {
			//Set the size of the line to 10 and make it black (0x000000)
			e.target.parent.getChildByName("shapes").graphics.lineStyle(10, "0x000000")
			//Move drawing point to where the mouse is at (see moveDrawOnPlayer() for more depth)
			e.target.parent.getChildByName("shapes").graphics.moveTo(e.target.parent.getChildByName("shapes").mouseX,e.target.parent.getChildByName("shapes").mouseY);

			}

		}
		
		private function enableBucket(e:MouseEvent):void 
		{
			tools.bucket.visible = true;
			tools.pencil.visible = false;
			myColorPicker.visible = false
			
			//Remove bucket event listeners
			player.removeEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
			player.removeEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
			myColorPicker.removeEventListener(Event.CHANGE, colorChangedPencil)
			
			player.addEventListener(MouseEvent.CLICK, showPicker)

			//See if our color has changed
			myColorPicker.addEventListener(Event.CHANGE, colorChanged)
			
			//Remove old event listeners
			player.removeEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
			player.removeEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
			player.removeEventListener(MouseEvent.MOUSE_MOVE, moveDrawOnPlayer)
		}
		
		//Placeholder function for when our ColorPicker has chosen a new pencil color
		private function colorChangedPencil(e:Event):void 
		{
			
		}
		
		private function colorChanged(e:Event):void 
		{
			myColorPicker.visible = false;
			var myChange:ColorTransform = new ColorTransform();
			myChange.color = new uint("0x" + e.target.hexValue)
			myChangedObject.transform.colorTransform = myChange
		}
		
		private function showPicker(e:MouseEvent):void 
		{
			if (e.target.name == "color") {
				myColorPicker.visible = !myColorPicker.visible 
				myColorPicker.move(stage.mouseX, stage.mouseY)
				myChangedObject = MovieClip(e.target)
				myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
			}
			
		}
		
	}
	
}

The purpose of this tutorial is not to cover drawing on Shape objects. That is fully covered by Carlos's tutorial. Right now, we are only learning the techniques for drawing onto the correct object. If you are confused on how we are accessing the right shape object, please re-read Step 12 for the full explanation.


Step 14: Drawing With Color

Now we can move on to drawing with a color selected from the ColorPicker. This is quite similar to the process that we used on the bucket tool.

Let's begin by adding a new variable outside all of the functions, but inside the class. This is what our program will use to store the current color of the pencil.

	var pencilColor:String = "000000";

Now let's move down to our drawOnPlayer() function.Focus your attention on the line that sets the lineStyle() of the shape we are drawing on. The second parameter in the function should be "0x000000". Change ONLY that parameter to:

	uint("0x"+pencilColor)

This is basically telling it to draw use the RBG code of our ColorPicker while adding the "0x" necessary to complete the color.

Here is what the line of code should look like now:

	e.target.parent.getChildByName("shapes").graphics.lineStyle(10, uint("0x"+pencilColor))

Finally, we need to complete the colorChangedPencil() function, which is called when a new pencil color is selected. Go down to it and add this line of code:

	pencilColor = e.target.hexValue

This is simply assigning the hexValue or RBG code of our ColorPicker to our pencilColor variable.


Step 15: Extending the Buttons Panel

In the next step, we are going to work on adding a new feature to our game. Unfortunately, we can't just leave a lot of placeholder room inside the panel in case we might happen to add another feature. You can use this as a quick and dirty way to extend the panel to make more room for other buttons and tools for our application.

Step 1: Select

Select all objects inside our Options MovieClip.

Step 2: Shift

Hold down the Shift key and press the Left key to slide the MovieClip to the left.

Step 3: Stretch

Use the mouse tool and stretch the corners of our panel filling (the gray color) as well as our outlines across the screen.

Step 4: ReAdjust

Make sure to modify any coordinate based objects. For example, we now need to change the location of the pencil's ColorPicker because our Pencil Tool button moved.

	myColorPicker.move(440, 20);

Step 16: Resetting our Data

Like any good drawing program, we need to give the player a way to restart his project. What better than a restart button for those users who can't make perfect drawing decisions? Let's begin by creating a new Button called Restart and adding it to our tools panel.

I'll be using this button (It's in the FLA):

Place one on the tools movie clip and give it an instance name of "reset". Next add the following event listener to our constructor function:

	tools.reset.addEventListener(MouseEvent.CLICK,resetEverything)

Now add this event handler function to our class:

private function resetEverything(e:MouseEvent):void 
{
	//Looping through all of the objects in our drawableParts array (all of our drawable objects)
	for (var i:int = 0; i < drawableParts.length; i++ ) {
		
		//Finding and removing our old shapes object
		drawableParts[i].removeChild(drawableParts[i].getChildByName("shapes"));
		
		//Creating a new shape object
		var myShape:Shape = new Shape()
		
		//Giving our new canvas a name
		myShape.name = "shapes"
		
		//Adding our object 
		drawableParts[i].addChild(myShape)
		
		//Masking our canvas to the object we are drawing on
		myShape.mask = drawableParts[i].maskclip
		
		//Finding the "color" MovieClip's colorTransform property and resetting it to a new ColorTransform object 
		drawableParts[i].getChildByName("color").transform.colorTransform = new ColorTransform()
	
	}
}

Read the comments in the function for a step by step explanation of what we are doing


Step 17: Integrating Animation

If you remember from the beginning of the tutorial, the goal of this tutorial was not to create a dress up game, but to create an advanced dress up component to be used in games. So far we've added a dynamic dress up component to the otherwise static character. Next, our goal is to integrate a simple walking animation with our player customization.

This is just a demo to show you how easily you can use these customizations in a real game.

To begin, I've created a simple animation with tweens. I've basically tweened the body part MovieClips to make the player seem like he is walking. You can view the animation below. Remember that the purpose of this tutorial is not to design the actual animation, but to learn how to integrate it with the application that we've already built. However, just like the other elements of the app, the animation is included in the source code.

Here you can see the timeline of the player MovieClip.

Now test the movie! The player should be animated. You can try to draw on the player's legs, and if you've been following the instructions properly, then when you draw, the drawing should stick onto the player's legs and animate with them. I will explain why in detail a little bit later.


Step 18: Draw > Animation Workflow

If you tried to draw on the player earlier, you might have had some difficulty drawing on the moving parts (DUH!). This is because we haven't implemented any real workflow or interface yet. In this step we will do all of that to make our application fully useable.

To start, let's add a line of code to our constructor to stop the player's animation:

	player.stop()

Next we need to extend our panel again. Just follow Step 15 and make the panel a bit longer

Now we need to add a "play animation" button. Just like the other UI elements, my button is like a switch. When you click on it, it toggles the visibility of another MovieClip to give the button the appearance of lighting up. The button's instance name is playgame while the lighting up MovieClip's instance name is playing. Check out the FLA or the preview SWF to see how these fit together.

Here is the code that we need to add to make this work... First add this to our constructor to disable the lighting up effect:

	tools.playing.visible = false;

Next add this EventListener to our constructor:

	tools.playgame.addEventListener(MouseEvent.CLICK,enableGame)

Finally, let's create this function in our class. At the moment, this is doing only two things. Firstly, it toggles our playing MovieClip's visibility. Then, it checks to see if the MovieClip is visible. If so, it starts our player's animation. Otherwise, it stops the animation at its first frame.

private function enableGame(e:MouseEvent):void 
{
	tools.playing.visible = !tools.playing.visible
	
	if (tools.playing.visible) {
		
		player.play()
	}
	else {
		
		player.gotoAndStop(1)

	}
}

Congratulations, you have now implemented a basic animation engine into our customizing program.


Step 19: Some Simple Game Logic

Everything is looking good, but what fun is a game without user interactivity? In this step we are going to add some simple interactivity to our game. To begin, download Senocular's KeyObject class here . This will make our logic much easier to write.

We are going to have to make a quick change to the class. Open it up. On the first line replace the:

	package com.senocular.utils {

with:

	package{

Now we can start by importing the class. Remember to put it in the directory of our Main class. Add this import statement next to the other ones:

	import KeyObject

To set up the KeyObject class. Just create a new variable key like so:

	var key:KeyObject;

And assign it to a new instance of the KeyObject class while adding in the Stage property, like so:

	key = new KeyObject(stage);

Either put that line of code in the constructor, or, if that doesn't work, add this line to the constructor:

	addEventListener(Event.ADDED_TO_STAGE, onAddToStage);

...and then add a new function to handle that event:

private function onAddToStage(e:Event):void 
{
	removeEventListener(Event.ADDED_TO_STAGE, onAddToStage);
	key = new KeyObject(stage);
}

If you don't do this, it's possible that stage will not refer to anything at the point when you need to use it.

Next we need to create an ENTER_FRAME event listener. However, we should remove it when we are done. Add this code to your enableGame() function:

private function enableGame(e:MouseEvent):void 
{
	tools.playing.visible = !tools.playing.visible

	if (tools.playing.visible) {
		
		player.play()
		addEventListener(Event.ENTER_FRAME, enterFrame);	//new line
		
	}
	else {
		
		player.gotoAndStop(1)
		removeEventListener(Event.ENTER_FRAME, enterFrame);	//new line
		

	}
}

The meaning of this code should be pretty clear for you, so there is no real need to explain.

Now here's our enterFrame() function:

private function enterFrame(e:Event):void 
{
	//Checks with our key variable to check if the LEFT key is down 
	//and that the character hasn't gone off of the screen
	if (key.isDown(key.LEFT) && player.x > 0) { 
		
		//Moves the player a bit
		player.x -= 5;
		
		//Flips the player backwards
		player.scaleX = -1
		
	
	}
	//Checks if the RIGHT key is down and the player hasn't gone off the other side
	if (key.isDown(key.RIGHT) && player.x < 640) {
		//Moves the player a bit
		player.x += 5
		
		//Flips the player to normal 
		player.scaleX = 1
	}
}

Test your SWF, pressing the left and right arrow keys.


Step 20: Fixing ColorPicker Popups!

As you may have noticed, if we have the pencil tool active and we are making the player move, our ColorPicker keeps on opening up. Here is a quick and dirty fix for that! Simply make the commented changes to your enableGame() function:

private function enableGame(e:MouseEvent):void 
{
	tools.playing.visible = !tools.playing.visible

	if (tools.playing.visible) {
		
		player.play()
		addEventListener(Event.ENTER_FRAME, enterFrame);
		
		//New code: Moving the ColorPicker WAAAYYYY to the right
		myColorPicker.x = 10000;
	}
	else {
		
		player.gotoAndStop(1)
		removeEventListener(Event.ENTER_FRAME, enterFrame);
		
		//New code: Checks to see if the pencil tool is active...
		if (tools.pencil.visible) {
			//Moves the ColorPicker back to where it used to be
			myColorPicker.x = 440
		}

	}
}

We don't have to do anything with the bucket tool because it already moves the ColorPicker over to the location of the Mouse.


Conclusion

As you can see, creating a unique customization experience is not that hard. In fact, it is a very good way to let the player make his avatar or character "his". Truly, we have just skimmed the surface of the customization options available in Flash. See what else you can come up with!

Related Posts
  • Code
    Android SDK
    Create a Music Player on Android: User Controls0d63m preview image@2x
    We are building a simple music player app for Android in this series. So far, we have presented a list of the songs on the device and allowed the user to make selections from it, starting playback using the MediaPlayer class in a Service class. In this final part of the series, we will let the user control playback, including skipping to the next and previous tracks, fast-forwarding, rewinding, playing, pausing, and seeking to particular points in the track. We will also display a notification during playback so that the user can jump back to the music player after using other apps.Read More…
  • Code
    Android SDK
    Create a Music Player on Android: Song Playback0d63m preview image@2x
    In this series, we are creating a music player on Android using the MediaPlayer and MediaController classes. In the first part, we created the app and prepared the user interface for playback. We presented the list of songs on the user device and specified a method to execute when the user makes a selection. In this part of the series, we will implement a Service class to execute music playback continuously, even when the user is not directly interacting with the application.Read More…
  • Code
    Android SDK
    Create a Music Player on Android: Project Setup0d63m preview image@2x
    The Android platform provides resources for handling media playback, which your apps can use to create an interface between the user and their music files. In this tutorial series, we will create a basic music player application for Android. The app will present a list of songs on the user device, so that the user can select songs to play. The app will also present controls for interacting with playback and will continue playing when the user moves away from the app, with a notification displayed while playback elapses.Read More…
  • Code
    JavaScript & AJAX
    Connect 4 With Socket.ioSocket io wide retina preview
    Today we'll see how we can use Node.js and Socket.io to create a multiplayer Connect 4 style game.Read More…
  • Game Development
    Implementation
    Write Once, Publish Everywhere With HaxePunk: Making a GamePreviewretinaimage
    You've probably had this experience before: you hear about an awesome game, but then you find out that it's only coming out on the one platform that you don't own. It doesn't have to be this way. In this tutorial, you will learn how to use Haxe to make a game in one development platform that can target multiple gaming platforms, including Linux, Mac, Windows, iOS, Android, and Flash.Read More…
  • Code
    Android SDK
    Create a Hangman Game: User InteractionAndroid hangman game preview retina
    In this series, we are creating a Hangman game for the Android platform. So far, we've built the application's user interface, including images, drawables, and layouts. In this third and final installment, we are going to focus on user interaction.Read More…