1. Code
  2. Coding Fundamentals
  3. Game Development

Advanced Character Customization for Flash Games

Scroll to top

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.

1
2
package 
3
{
4
	import flash.display.Sprite;
5
	import flash.display.BitmapData
6
	import flash.net.FileReference
7
	import flash.display.Loader
8
	import flash.display.Bitmap
9
	import flash.display.MovieClip
10
	import fl.controls.ColorPicker
11
	import flash.events.Event
12
	import flash.events.MouseEvent
13
14
	
15
	public class  CustomCharacter extends Sprite
16
	{
17
		
18
	
19
		public function CustomCharacter():void {
20
		
21
		
22
		
23
		}
24
		
25
		
26
	}
27
	
28
	
29
	
30
}

(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.

1
2
package 
3
{
4
	import flash.display.Sprite;
5
	import flash.display.BitmapData
6
	import flash.events.Event;
7
	import flash.net.FileReference
8
	import flash.display.Loader
9
	import flash.display.Bitmap
10
	import flash.display.MovieClip
11
	import fl.controls.ColorPicker	
12
	import flash.events.MouseEvent
13
	
14
	public class  CustomCharacter extends Sprite
15
	{
16
		var myColorPicker:ColorPicker = new ColorPicker();
17
	
18
		public function CustomCharacter():void {
19
			
20
		myColorPicker.editable = true;
21
		myColorPicker.visible = false;
22
		addChild(myColorPicker);
23
		
24
		player.addEventListener(MouseEvent.CLICK, showPicker)
25
		myColorPicker.addEventListener(Event.CHANGE, colorChanged)
26
		
27
		}
28
		
29
		private function colorChanged(e:Event):void 
30
		{
31
			myColorPicker.visible = false;
32
		}
33
		
34
		private function showPicker(e:MouseEvent):void 
35
		{
36
			myColorPicker.visible = !myColorPicker.visible 
37
			myColorPicker.move(stage.mouseX,stage.mouseY)
38
			
39
		}
40
		
41
		
42
		
43
		
44
	}
45
	
46
	
47
	
48
}

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.

1
2
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:

1
2
package 
3
{
4
	import flash.display.Sprite;
5
	import flash.display.BitmapData
6
	import flash.events.Event;
7
	import flash.geom.ColorTransform;
8
	import flash.net.FileReference
9
	import flash.display.Loader
10
	import flash.display.Bitmap
11
	import flash.display.MovieClip
12
	import fl.controls.ColorPicker	
13
	import flash.events.MouseEvent
14
	
15
	public class CustomCharacter extends Sprite
16
	{
17
		var myColorPicker:ColorPicker = new ColorPicker();
18
		var myChangedObject:MovieClip;
19
		
20
		public function CustomCharacter():void {
21
		
22
		
23
		myColorPicker.editable = true;
24
		myColorPicker.visible = false;
25
		addChild(myColorPicker);
26
		
27
		player.addEventListener(MouseEvent.CLICK, showPicker)
28
		myColorPicker.addEventListener(Event.CHANGE, colorChanged)
29
		
30
		}
31
		
32
		private function colorChanged(e:Event):void 
33
		{
34
			myColorPicker.visible = false;
35
			var myChange:ColorTransform = new ColorTransform();
36
			myChange.color = new uint("0x" + e.target.hexValue)
37
			myChangedObject.transform.colorTransform = myChange
38
		}
39
		
40
		private function showPicker(e:MouseEvent):void 
41
		{
42
			if (e.target.name == "color") {
43
				myColorPicker.visible = !myColorPicker.visible 
44
				myColorPicker.move(stage.mouseX, stage.mouseY)
45
				myChangedObject = MovieClip(e.target)
46
				myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
47
			}
48
			
49
		}
50
		
51
		
52
		
53
		
54
	}
55
	
56
	
57
	
58
}

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.

1
2
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:

1
2
package 
3
{
4
	import flash.display.Sprite;
5
	import flash.display.BitmapData
6
	import flash.events.Event;
7
	import flash.geom.ColorTransform;
8
	import flash.net.FileReference
9
	import flash.display.Loader
10
	import flash.display.Bitmap
11
	import flash.display.MovieClip
12
	import fl.controls.ColorPicker	
13
	import flash.events.MouseEvent
14
	
15
	public class  CustomCharacter extends Sprite
16
	{
17
		var myColorPicker:ColorPicker = new ColorPicker();
18
		var myChangedObject:MovieClip;
19
		
20
		public function CustomCharacter():void {
21
		
22
		
23
		myColorPicker.editable = true;
24
		myColorPicker.visible = false;
25
		addChild(myColorPicker);
26
		
27
		
28
		tools.bucket.visible = false;
29
		tools.pencil.visible = false;
30
		
31
		tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
32
		tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
33
		
34
		
35
		}
36
		
37
		private function enablePencil(e:MouseEvent):void 
38
		{
39
			
40
		tools.bucket.visible = false;
41
		tools.pencil.visible = true;
42
		player.removeEventListener(MouseEvent.CLICK, showPicker)
43
		myColorPicker.removeEventListener(Event.CHANGE, colorChanged)
44
		
45
		}
46
		
47
		private function enableBucket(e:MouseEvent):void 
48
		{
49
		
50
		tools.bucket.visible = true;
51
		tools.pencil.visible = false;
52
		player.addEventListener(MouseEvent.CLICK, showPicker)
53
		myColorPicker.addEventListener(Event.CHANGE, colorChanged)
54
		
55
		
56
		}
57
		
58
		private function colorChanged(e:Event):void 
59
		{
60
			myColorPicker.visible = false;
61
			var myChange:ColorTransform = new ColorTransform();
62
			myChange.color = new uint("0x" + e.target.hexValue)
63
			myChangedObject.transform.colorTransform = myChange
64
		}
65
		
66
		private function showPicker(e:MouseEvent):void 
67
		{
68
			if (e.target.name == "color") {
69
				myColorPicker.visible = !myColorPicker.visible 
70
				myColorPicker.move(stage.mouseX, stage.mouseY)
71
				myChangedObject = MovieClip(e.target)
72
				myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
73
74
			}
75
			
76
		}
77
		
78
		
79
		
80
		
81
	}
82
	
83
	
84
	
85
}

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:

1
2
	myColorPicker.visible = true
3
	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:

1
2
	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:

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

Sadly, that doesn't work as planned.

1
2
TypeError: Error #1009: Cannot access a property or method of a null object reference.
3
	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:

1
2
public class  CustomCharacter extends Sprite
3
{
4
	var myColorPicker:ColorPicker = new ColorPicker();
5
	var myChangedObject:MovieClip;
6
	var bucket:Boolean = false
7
	var drawableParts:Array 
8
	
9
	public function CustomCharacter():void {
10
	
11
		drawableParts = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair]
12
13
		myColorPicker.editable = true;
14
		myColorPicker.visible = false;
15
		addChild(myColorPicker);
16
		
17
		
18
		tools.bucket.visible = false;
19
		tools.pencil.visible = false;
20
		
21
		tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
22
		tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
23
	}

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.

1
2
	import flash.display.Shape;

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

1
2
for (var i:int = 0; i < drawableParts.length;i++ ) {
3
	var myShape:Shape = new Shape()
4
	
5
	myShape.graphics.lineStyle(1,0x330000);
6
	myShape.graphics.beginFill(0x3312FF,0.5);
7
	myShape.graphics.drawRect(0,0,drawableParts[i].width * 3,drawableParts[i].height * 3);
8
	myShape.graphics.endFill();
9
	
10
	myShape.name = "shapes"
11
	
12
	drawableParts[i].addChild(myShape)
13
}

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:

1
2
	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..

1
2
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.

1
2
package 
3
{
4
	import flash.display.Shape;
5
	import flash.display.Sprite;
6
	import flash.display.BitmapData
7
	import flash.events.Event;
8
	import flash.geom.ColorTransform;
9
	import flash.net.FileReference
10
	import flash.display.Loader
11
	import flash.display.Bitmap
12
	import flash.display.MovieClip
13
	import fl.controls.ColorPicker	
14
	import flash.events.MouseEvent
15
	
16
	public class  CustomCharacter extends Sprite
17
	{
18
		var myColorPicker:ColorPicker = new ColorPicker();
19
		var myChangedObject:MovieClip;
20
		var bucket:Boolean = false
21
		var drawableParts:Array 
22
		
23
		//A boolean to check to see if the mouse is drawing

24
		var drawing:Boolean = false
25
		
26
		public function CustomCharacter():void {
27
			drawableParts = [player.arm1,player.arm2,player.leg1,player.leg2,player.head,player.shirt,player.hair]
28
			myColorPicker.editable = true;
29
			myColorPicker.visible = false;
30
			addChild(myColorPicker);
31
			
32
			
33
			tools.bucket.visible = false;
34
			tools.pencil.visible = false;
35
			
36
			tools.bucket_btn.addEventListener(MouseEvent.CLICK,enableBucket)
37
			tools.pencil_btn.addEventListener(MouseEvent.CLICK, enablePencil)
38
			for (var i:int = 0; i < drawableParts.length;i++ ) {
39
				var myShape:Shape = new Shape()
40
				
41
				myShape.name = "shapes"
42
				
43
				drawableParts[i].addChild(myShape)
44
				myShape.mask = drawableParts[i].maskclip
45
			}
46
		}
47
		
48
		
49
		private function enablePencil(e:MouseEvent):void 
50
		{
51
			tools.bucket.visible = false;
52
			tools.pencil.visible = true;
53
			player.removeEventListener(MouseEvent.CLICK, showPicker)
54
			
55
			//Removing eventListener placed by our bucket tool

56
			myColorPicker.removeEventListener(Event.CHANGE, colorChanged)
57
			
58
			//Checks to see when our ColorPicker changes color while Pencil is selected

59
			myColorPicker.addEventListener(Event.CHANGE, colorChangedPencil)
60
			
61
			//Checks to see if the mouse is down, up, or moving

62
			player.addEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
63
			player.addEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
64
			player.addEventListener(MouseEvent.MOUSE_MOVE, moveDrawOnPlayer)</b>

65
66
			myColorPicker.visible = true
67
			myColorPicker.move(515, 20);
68
		}
69
		
70
		//Function to check for movement of the mouse, while drawing

71
		private function moveDrawOnPlayer(e:MouseEvent):void 
72
		{
73
			//If our mouse is hovering over the filling of the player and if we are indeed drawing

74
			if (e.target.name == "color" && drawing) {
75
					//Draw a line from the graphical section of our shape movieclip to the location of the mouse

76
					//We need to use ourCanvas.mouseX or mouseY because that gives us local coordinates of the mouse that our canvas can use

77
					e.target.parent.getChildByName("shapes").graphics.lineTo(e.target.parent.getChildByName("shapes").mouseX,e.target.parent.getChildByName("shapes").mouseY);
78
			}
79
80
		}
81
		
82
		private function dontDrawOnPlayer(e:MouseEvent):void 
83
		{
84
			//When you release the mouse, stop drawing

85
			drawing = false;
86
			
87
		}
88
89
		//new function

90
		private function drawOnPlayer(e:MouseEvent):void 
91
		{
92
			//When you click, start drawing

93
			drawing = true;
94
			
95
			//If you are clicking on a "color" MovieClip

96
			if (e.target.name == "color" ) {
97
			//Set the size of the line to 10 and make it black (0x000000)

98
			e.target.parent.getChildByName("shapes").graphics.lineStyle(10, "0x000000")
99
			//Move drawing point to where the mouse is at (see moveDrawOnPlayer() for more depth)

100
			e.target.parent.getChildByName("shapes").graphics.moveTo(e.target.parent.getChildByName("shapes").mouseX,e.target.parent.getChildByName("shapes").mouseY);
101
102
			}
103
104
		}
105
		
106
		private function enableBucket(e:MouseEvent):void 
107
		{
108
			tools.bucket.visible = true;
109
			tools.pencil.visible = false;
110
			myColorPicker.visible = false
111
			
112
			//Remove bucket event listeners

113
			player.removeEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
114
			player.removeEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
115
			myColorPicker.removeEventListener(Event.CHANGE, colorChangedPencil)
116
			
117
			player.addEventListener(MouseEvent.CLICK, showPicker)
118
119
			//See if our color has changed

120
			myColorPicker.addEventListener(Event.CHANGE, colorChanged)
121
			
122
			//Remove old event listeners

123
			player.removeEventListener(MouseEvent.MOUSE_DOWN, drawOnPlayer)
124
			player.removeEventListener(MouseEvent.MOUSE_UP, dontDrawOnPlayer)
125
			player.removeEventListener(MouseEvent.MOUSE_MOVE, moveDrawOnPlayer)
126
		}
127
		
128
		//Placeholder function for when our ColorPicker has chosen a new pencil color

129
		private function colorChangedPencil(e:Event):void 
130
		{
131
			
132
		}
133
		
134
		private function colorChanged(e:Event):void 
135
		{
136
			myColorPicker.visible = false;
137
			var myChange:ColorTransform = new ColorTransform();
138
			myChange.color = new uint("0x" + e.target.hexValue)
139
			myChangedObject.transform.colorTransform = myChange
140
		}
141
		
142
		private function showPicker(e:MouseEvent):void 
143
		{
144
			if (e.target.name == "color") {
145
				myColorPicker.visible = !myColorPicker.visible 
146
				myColorPicker.move(stage.mouseX, stage.mouseY)
147
				myChangedObject = MovieClip(e.target)
148
				myColorPicker.selectedColor = uint(myChangedObject.transform.colorTransform.color)
149
			}
150
			
151
		}
152
		
153
	}
154
	
155
}

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.

1
2
	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:

1
2
	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:

1
2
	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:

1
2
	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.

1
2
	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:

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

Now add this event handler function to our class:

1
2
private function resetEverything(e:MouseEvent):void 
3
{
4
	//Looping through all of the objects in our drawableParts array (all of our drawable objects)

5
	for (var i:int = 0; i < drawableParts.length; i++ ) {
6
		
7
		//Finding and removing our old <em>shapes</em> object

8
		drawableParts[i].removeChild(drawableParts[i].getChildByName("shapes"));
9
		
10
		//Creating a new shape object

11
		var myShape:Shape = new Shape()
12
		
13
		//Giving our new canvas a name

14
		myShape.name = "shapes"
15
		
16
		//Adding our object 

17
		drawableParts[i].addChild(myShape)
18
		
19
		//Masking our canvas to the object we are drawing on

20
		myShape.mask = drawableParts[i].maskclip
21
		
22
		//Finding the "color" MovieClip's colorTransform property and resetting it to a new ColorTransform object 

23
		drawableParts[i].getChildByName("color").transform.colorTransform = new ColorTransform()
24
	
25
	}
26
}

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:

1
2
	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:

1
2
	tools.playing.visible = false;

Next add this EventListener to our constructor:

1
2
	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.

1
2
private function enableGame(e:MouseEvent):void 
3
{
4
	tools.playing.visible = !tools.playing.visible
5
	
6
	if (tools.playing.visible) {
7
		
8
		player.play()
9
	}
10
	else {
11
		
12
		player.gotoAndStop(1)
13
14
	}
15
}

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:

1
2
	package com.senocular.utils {

with:

1
2
	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:

1
2
	import KeyObject

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

1
2
	var key:KeyObject;

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

1
2
	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:

1
2
	addEventListener(Event.ADDED_TO_STAGE, onAddToStage);

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

1
2
private function onAddToStage(e:Event):void 
3
{
4
	removeEventListener(Event.ADDED_TO_STAGE, onAddToStage);
5
	key = new KeyObject(stage);
6
}

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:

1
2
private function enableGame(e:MouseEvent):void 
3
{
4
	tools.playing.visible = !tools.playing.visible
5
6
	if (tools.playing.visible) {
7
		
8
		player.play()
9
		addEventListener(Event.ENTER_FRAME, enterFrame);	//new line

10
		
11
	}
12
	else {
13
		
14
		player.gotoAndStop(1)
15
		removeEventListener(Event.ENTER_FRAME, enterFrame);	//new line

16
		
17
18
	}
19
}

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:

1
2
private function enterFrame(e:Event):void 
3
{
4
	//Checks with our key variable to check if the LEFT key is down 

5
	//and that the character hasn't gone off of the screen

6
	if (key.isDown(key.LEFT) && player.x > 0) { 
7
		
8
		//Moves the player a bit

9
		player.x -= 5;
10
		
11
		//Flips the player backwards

12
		player.scaleX = -1
13
		
14
	
15
	}
16
	//Checks if the RIGHT key is down and the player hasn't gone off the other side

17
	if (key.isDown(key.RIGHT) && player.x < 640) {
18
		//Moves the player a bit

19
		player.x += 5
20
		
21
		//Flips the player to normal 

22
		player.scaleX = 1
23
	}
24
}

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:

1
2
private function enableGame(e:MouseEvent):void 
3
{
4
	tools.playing.visible = !tools.playing.visible
5
6
	if (tools.playing.visible) {
7
		
8
		player.play()
9
		addEventListener(Event.ENTER_FRAME, enterFrame);
10
		
11
		//New code: Moving the ColorPicker WAAAYYYY to the right

12
		myColorPicker.x = 10000;
13
	}
14
	else {
15
		
16
		player.gotoAndStop(1)
17
		removeEventListener(Event.ENTER_FRAME, enterFrame);
18
		
19
		//New code: Checks to see if the pencil tool is active...

20
		if (tools.pencil.visible) {
21
			//Moves the ColorPicker back to where it used to be

22
			myColorPicker.x = 440
23
		}
24
25
	}
26
}

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!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.