Jul 14 2008

Flash Game Creation - Raiden Part 2

Published by Andy G. Cook at 4:39 pm under Actionscript 3, Flash, Game Design, Intermediate

This post is a continuation of a previous post, Raiden Part 1.

WARNING! REFRESH THIS PAGE EVERY ONCE IN A WHILE! THE SWFS DO NOT HAVE CHECKS BECAUSE I WANTED YOU TO ACTUALLY SEE THE PROBLEMS STEP BY STEP AND BE ABLE TO FIX THEM. BECAUSE OF THIS, YOUR BROWSER WILL START EATING A LOT OF MEMORY AND POSSIBLY FREEZE YOUR COMPUTER!

Now it is time to add the background. For this game, it is just going to be a simple background of stars.

Adding a star:




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
package
{
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
 
	public class Main extends Sprite
	{
		private var GameShip:Ship;
 
		private var bLeftKeyDown:Boolean;
		private var bUpKeyDown:Boolean;
		private var bRightKeyDown:Boolean;
		private var bDownKeyDown:Boolean;
 
		private var nPower:Number = 1;
		private var nSpeedX:Number = 0;
		private var nSpeedY:Number = 0;
		private var nFriction:Number = .95;
 
		private var Star:Starlight;
 
		public function Main ( ) : void
		{
			GameShip = new Ship ( );
			this.addChild(GameShip);
			GameShip.x = stage.stageWidth/2;
			GameShip.y = stage.stageHeight - 50;
 
			Star = new Starlight ();
			Star.x = Math.floor ( Math.random() * stage.stageWidth );
			Star.y = Math.floor ( Math.random() * stage.stageHeight );
			this.addChild(Star);
 
 
			stage.addEventListener ( KeyboardEvent.KEY_DOWN, keyDownHandler );
			stage.addEventListener ( KeyboardEvent.KEY_UP, keyUpHandler ); 
			stage.addEventListener ( Event.ENTER_FRAME, onEnterFrameHandler );
		}
 
		private function keyDownHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = true;
				break;
 
				case 38:
				bUpKeyDown = true;
				break;
 
				case 39:
				bRightKeyDown = true;
				break;
 
				case 40:
				bDownKeyDown = true;
				break;
			}
		}
 
		private function keyUpHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = false;
				break;
 
				case 38:
				bUpKeyDown = false;
				break;
 
				case 39:
				bRightKeyDown = false;
				break;
 
				case 40:
				bDownKeyDown = false;
				break;
			}
		}
 
		private function onEnterFrameHandler ( E:Event ) : void
		{
			if ( bLeftKeyDown )
			{
				if ( nSpeedX > -10 )
				{
					nSpeedX -= nPower;
				}
			}
 
			if ( bUpKeyDown )
			{
				if ( nSpeedY > -10 )
				{
					nSpeedY -= nPower;
				}
			}
 
			if ( bRightKeyDown )
			{
				if ( nSpeedX < 10 )
				{
					nSpeedX += nPower;
				}
			}
 
			if ( bDownKeyDown )
			{
				if ( nSpeedY < 10 )
				{
					nSpeedY += nPower;
				}
			}
 
			GameShip.x += nSpeedX;
			GameShip.y += nSpeedY;
 
			nSpeedX *= nFriction;
			nSpeedY *= nFriction;
 
			if ( nSpeedX * nSpeedX < .001 )
			{
				nSpeedX = 0;
			}
 
			if ( nSpeedY * nSpeedY < .001 )
			{
				nSpeedY = 0;
			}
 
			if ( GameShip.x + GameShip.width/2 > stage.stageWidth )
			{
				GameShip.x = stage.stageWidth - GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.x - GameShip.width/2 < 0 )
			{
				GameShip.x = 0 + GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.y + GameShip.height/2 > stage.stageHeight )
			{
				GameShip.y = stage.stageHeight - GameShip.height/2;
				nSpeedY = 0;
			}
 
			if ( GameShip.y - GameShip.height/2 < 0 )
			{
				GameShip.y = 0 + GameShip.height/2;
				nSpeedY = 0;
			}
		}
	}
}

Line 23: Declared a variable called Star of type Starlight. Don’t forget to put linkage on your GameStar movieclip in the library. I just picked Starlight to show the differences between linkage, the library name, and the actual variable name.

Lines 32-35: Adding the star to the stage the same way the ship was added to the main stage.

Adding stars with an interval:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package
{
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.utils.setInterval;
 
	public class Main extends Sprite
	{
		private var GameShip:Ship;
 
		private var bLeftKeyDown:Boolean;
		private var bUpKeyDown:Boolean;
		private var bRightKeyDown:Boolean;
		private var bDownKeyDown:Boolean;
 
		private var nPower:Number = 1;
		private var nSpeedX:Number = 0;
		private var nSpeedY:Number = 0;
		private var nFriction:Number = .95;
 
		private var uintAddStar:uint;
 
		public function Main ( ) : void
		{
			GameShip = new Ship ( );
			this.addChild(GameShip);
			GameShip.x = stage.stageWidth/2;
			GameShip.y = stage.stageHeight - 50;
 
			stage.addEventListener ( KeyboardEvent.KEY_DOWN, keyDownHandler );
			stage.addEventListener ( KeyboardEvent.KEY_UP, keyUpHandler ); 
			stage.addEventListener ( Event.ENTER_FRAME, onEnterFrameHandler );
 
			uintAddStar = setInterval ( addAStar, 500 );
		}
 
		private function addAStar ( ) : void
		{
			var Star:Starlight = new Starlight ();
			Star.x = Math.floor ( Math.random() * stage.stageWidth );
			Star.y = Math.floor ( Math.random() * stage.stageHeight );
			this.addChild(Star);
		}
 
		private function keyDownHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = true;
				break;
 
				case 38:
				bUpKeyDown = true;
				break;
 
				case 39:
				bRightKeyDown = true;
				break;
 
				case 40:
				bDownKeyDown = true;
				break;
			}
		}
 
		private function keyUpHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = false;
				break;
 
				case 38:
				bUpKeyDown = false;
				break;
 
				case 39:
				bRightKeyDown = false;
				break;
 
				case 40:
				bDownKeyDown = false;
				break;
			}
		}
 
		private function onEnterFrameHandler ( E:Event ) : void
		{
			if ( bLeftKeyDown )
			{
				if ( nSpeedX > -10 )
				{
					nSpeedX -= nPower;
				}
			}
 
			if ( bUpKeyDown )
			{
				if ( nSpeedY > -10 )
				{
					nSpeedY -= nPower;
				}
			}
 
			if ( bRightKeyDown )
			{
				if ( nSpeedX < 10 )
				{
					nSpeedX += nPower;
				}
			}
 
			if ( bDownKeyDown )
			{
				if ( nSpeedY < 10 )
				{
					nSpeedY += nPower;
				}
			}
 
			GameShip.x += nSpeedX;
			GameShip.y += nSpeedY;
 
			nSpeedX *= nFriction;
			nSpeedY *= nFriction;
 
			if ( nSpeedX * nSpeedX < .001 )
			{
				nSpeedX = 0;
			}
 
			if ( nSpeedY * nSpeedY < .001 )
			{
				nSpeedY = 0;
			}
 
			if ( GameShip.x + GameShip.width/2 > stage.stageWidth )
			{
				GameShip.x = stage.stageWidth - GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.x - GameShip.width/2 < 0 )
			{
				GameShip.x = 0 + GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.y + GameShip.height/2 > stage.stageHeight )
			{
				GameShip.y = stage.stageHeight - GameShip.height/2;
				nSpeedY = 0;
			}
 
			if ( GameShip.y - GameShip.height/2 < 0 )
			{
				GameShip.y = 0 + GameShip.height/2;
				nSpeedY = 0;
			}
		}
	}
}

Line 8: Imported the setInterval method.

Line 24: Took out the declaration of Star and replaced it with a declaration of uintAddStar. All intervals are of type uint.

Line 37: Defined uintAddStar to be an interval with the setInterval method. Intervals allow a function to be ran at a given amount of time forever (or until you tell it to stop). The first parameter is always the name of the function you want to run. The second parameter is the interval you want the function to run in milliseconds.

Lines 40-46: Moved the code to add the star into the function addAStar. This had to be done so the interval could run it.

Prepopulating the stage with stars:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package
{
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
 
	import flash.utils.setInterval;
 
	public class Main extends Sprite
	{
		private var GameShip:Ship;
 
		private var bLeftKeyDown:Boolean;
		private var bUpKeyDown:Boolean;
		private var bRightKeyDown:Boolean;
		private var bDownKeyDown:Boolean;
 
		private var nPower:Number = 1;
		private var nSpeedX:Number = 0;
		private var nSpeedY:Number = 0;
		private var nFriction:Number = .95;
 
		private var uintAddStar:uint;
 
		public function Main ( ) : void
		{
			GameShip = new Ship ( );
			this.addChild(GameShip);
			GameShip.x = stage.stageWidth/2;
			GameShip.y = stage.stageHeight - 50;
 
			stage.addEventListener ( KeyboardEvent.KEY_DOWN, keyDownHandler );
			stage.addEventListener ( KeyboardEvent.KEY_UP, keyUpHandler ); 
			stage.addEventListener ( Event.ENTER_FRAME, onEnterFrameHandler );
 
			uintAddStar = setInterval ( addAStar, 500 );
 
			for ( var i = 0; i < 50; i++ )
			{
				addAStar();
			}
		}
 
		private function addAStar ( ) : void
		{
			var Star:Starlight = new Starlight ();
			Star.x = Math.floor ( Math.random() * stage.stageWidth );
			Star.y = Math.floor ( Math.random() * stage.stageHeight );
			this.addChild(Star);
		}
 
		private function keyDownHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = true;
				break;
 
				case 38:
				bUpKeyDown = true;
				break;
 
				case 39:
				bRightKeyDown = true;
				break;
 
				case 40:
				bDownKeyDown = true;
				break;
			}
		}
 
		private function keyUpHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = false;
				break;
 
				case 38:
				bUpKeyDown = false;
				break;
 
				case 39:
				bRightKeyDown = false;
				break;
 
				case 40:
				bDownKeyDown = false;
				break;
			}
		}
 
		private function onEnterFrameHandler ( E:Event ) : void
		{
			if ( bLeftKeyDown )
			{
				if ( nSpeedX > -10 )
				{
					nSpeedX -= nPower;
				}
			}
 
			if ( bUpKeyDown )
			{
				if ( nSpeedY > -10 )
				{
					nSpeedY -= nPower;
				}
			}
 
			if ( bRightKeyDown )
			{
				if ( nSpeedX < 10 )
				{
					nSpeedX += nPower;
				}
			}
 
			if ( bDownKeyDown )
			{
				if ( nSpeedY < 10 )
				{
					nSpeedY += nPower;
				}
			}
 
			GameShip.x += nSpeedX;
			GameShip.y += nSpeedY;
 
			nSpeedX *= nFriction;
			nSpeedY *= nFriction;
 
			if ( nSpeedX * nSpeedX < .001 )
			{
				nSpeedX = 0;
			}
 
			if ( nSpeedY * nSpeedY < .001 )
			{
				nSpeedY = 0;
			}
 
			if ( GameShip.x + GameShip.width/2 > stage.stageWidth )
			{
				GameShip.x = stage.stageWidth - GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.x - GameShip.width/2 < 0 )
			{
				GameShip.x = 0 + GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.y + GameShip.height/2 > stage.stageHeight )
			{
				GameShip.y = stage.stageHeight - GameShip.height/2;
				nSpeedY = 0;
			}
 
			if ( GameShip.y - GameShip.height/2 < 0 )
			{
				GameShip.y = 0 + GameShip.height/2;
				nSpeedY = 0;
			}
		}
	}
}

Lines 39-42: Wrote a for loop to add 50 stars to the stage. It just runs the addAStar function 50 times.

Falling stars:

We have to make a new class to make the stars fall. It is the Starlight class. So far, we have been letting Flash create the classes for us, but now we are actually going to write the Starlight class and override Flash’s default class.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package
{
	import flash.display.MovieClip;
	import flash.events.Event;
 
	public class Starlight extends MovieClip
	{
 
		public function Starlight ( ) : void
		{
			this.addEventListener ( Event.ENTER_FRAME, moveStar );
		}
 
		private function moveStar ( E:Event ) :void
		{
			this.y += 3;
		}
	}
}

Lines 1-12: Declaring the class, constructor, and adding an ENTER_FRAME event listener to run the function moveStar.

Lines 14-17: Creating function moveStar to move “this” 3 pixels down every frame. When you are inside a class, and you refer to “this”, you are refering to the instance of that class. So a “this” call inside the Starlight class will refer to that specific Starlight and none of the other Starlights. This idea is called Scope and can be bit confusing at first. Read up on Scope if you don’t understand it already.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package
{
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.utils.setInterval;
 
	public class Main extends Sprite
	{
		private var GameShip:Ship;
 
		private var bLeftKeyDown:Boolean;
		private var bUpKeyDown:Boolean;
		private var bRightKeyDown:Boolean;
		private var bDownKeyDown:Boolean;
 
		private var nPower:Number = 1;
		private var nSpeedX:Number = 0;
		private var nSpeedY:Number = 0;
		private var nFriction:Number = .95;
 
		private var uintAddStar:uint;
 
		public function Main ( ) : void
		{
			GameShip = new Ship ( );
			this.addChild(GameShip);
			GameShip.x = stage.stageWidth/2;
			GameShip.y = stage.stageHeight - 50;
 
			stage.addEventListener ( KeyboardEvent.KEY_DOWN, keyDownHandler );
			stage.addEventListener ( KeyboardEvent.KEY_UP, keyUpHandler ); 
			stage.addEventListener ( Event.ENTER_FRAME, onEnterFrameHandler );
 
			uintAddStar = setInterval ( addAStar, 500, false );
 
			for ( var i = 0; i < 50; i++ )
			{
				addAStar( true );
			}
		}
 
		private function addAStar ( BPopulate:Boolean ) : void
		{
			var Star:Starlight = new Starlight ();
 
			if ( BPopulate )
			{
				Star.y = Math.floor ( Math.random() * stage.stageHeight );
			}
			else
			{
				Star.y = -20;
			}
 
			Star.x = Math.floor ( Math.random() * stage.stageWidth );
			this.addChild(Star);
		}
 
		private function keyDownHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = true;
				break;
 
				case 38:
				bUpKeyDown = true;
				break;
 
				case 39:
				bRightKeyDown = true;
				break;
 
				case 40:
				bDownKeyDown = true;
				break;
			}
		}
 
		private function keyUpHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = false;
				break;
 
				case 38:
				bUpKeyDown = false;
				break;
 
				case 39:
				bRightKeyDown = false;
				break;
 
				case 40:
				bDownKeyDown = false;
				break;
			}
		}
 
		private function onEnterFrameHandler ( E:Event ) : void
		{
			if ( bLeftKeyDown )
			{
				if ( nSpeedX > -10 )
				{
					nSpeedX -= nPower;
				}
			}
 
			if ( bUpKeyDown )
			{
				if ( nSpeedY > -10 )
				{
					nSpeedY -= nPower;
				}
			}
 
			if ( bRightKeyDown )
			{
				if ( nSpeedX < 10 )
				{
					nSpeedX += nPower;
				}
			}
 
			if ( bDownKeyDown )
			{
				if ( nSpeedY < 10 )
				{
					nSpeedY += nPower;
				}
			}
 
			GameShip.x += nSpeedX;
			GameShip.y += nSpeedY;
 
			nSpeedX *= nFriction;
			nSpeedY *= nFriction;
 
			if ( nSpeedX * nSpeedX < .001 )
			{
				nSpeedX = 0;
			}
 
			if ( nSpeedY * nSpeedY < .001 )
			{
				nSpeedY = 0;
			}
 
			if ( GameShip.x + GameShip.width/2 > stage.stageWidth )
			{
				GameShip.x = stage.stageWidth - GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.x - GameShip.width/2 < 0 )
			{
				GameShip.x = 0 + GameShip.width/2;
				nSpeedX = 0;
			}
 
			if ( GameShip.y + GameShip.height/2 > stage.stageHeight )
			{
				GameShip.y = stage.stageHeight - GameShip.height/2;
				nSpeedY = 0;
			}
 
			if ( GameShip.y - GameShip.height/2 < 0 )
			{
				GameShip.y = 0 + GameShip.height/2;
				nSpeedY = 0;
			}
		}
	}
}

Line 37: Passing a false argument at the end of the interval. You can pass parameters to the function you want to run on the interval just by putting them after the first two required parameters (function, duration).

Lines 39-42: Modified my for loop. I am having addAStar in the for loop pass an argument of true now.

Lines 45-61: Changed the addAStar function. The stars that are being added now move. New stars shouldn’t be added randomly into the stage as the player is playing, so they should be added off the top of the screen. However, if you just change the Y position of the star, the prepopulating stars will all start at the top of the stage. This is why we need an if statement. If BPopulate is true, which it will be in the for loop in Lines 39-42, then the stars start at random X and Y positions. If the BPopulate variable is false, which it will be if it is from the interval on Line 37, then the stars should start at -20 for their Y position.

Giving the stars perspective:

The stars look awkward because they are all going the same speed. If you give them random speeds, then it is still going to look awkward because why would one star go faster than the other star if your ship is going a constant speed? You can create a really nice effect by simulating perspective with the stars.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package
{
	import flash.display.MovieClip;
	import flash.events.Event;
 
	public class Starlight extends MovieClip
	{
 
		public function Starlight ( ) : void
		{
			this.scaleX = this.scaleY = Math.random() + .1;
			this.addEventListener ( Event.ENTER_FRAME, moveStar );
		}
 
		private function moveStar ( E:Event ) :void
		{
			this.y += 1 * this.scaleY;
		}
	}
}

Line 11: Making the star have a random scaleX and random scaleY. Setting them equal to each other to keep the right proportions of the star. Also adding .1 to it so that all the stars are big enough for the human eye to see.

Line 17: Making the star’s speed depend on its scale. The smaller the star is, the slower it appears to travel.

Removing the stars and fixing depths:



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package
{
	import flash.display.Sprite;
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.events.KeyboardEvent;
	import flash.events.Event;
	import flash.utils.setInterval;
 
	public class Main extends Sprite
	{
		private var GameShip:Ship;
 
		private var bLeftKeyDown:Boolean;
		private var bUpKeyDown:Boolean;
		private var bRightKeyDown:Boolean;
		private var bDownKeyDown:Boolean;
 
		private var nPower:Number = 1;
		private var nSpeedX:Number = 0;
		private var nSpeedY:Number = 0;
		private var nFriction:Number = .95;
 
		private var uintAddStar:uint;
 
		private var mcStarContainer:MovieClip;
 
		public function Main ( ) : void
		{
			mcStarContainer = new MovieClip ();
			this.addChild(mcStarContainer);
 
			GameShip = new Ship ( );
			this.addChild(GameShip);
			GameShip.x = stage.stageWidth/2;
			GameShip.y = stage.stageHeight - 50;
 
			stage.addEventListener ( KeyboardEvent.KEY_DOWN, keyDownHandler );
			stage.addEventListener ( KeyboardEvent.KEY_UP, keyUpHandler ); 
			stage.addEventListener ( Event.ENTER_FRAME, onEnterFrameHandler );
 
			uintAddStar = setInterval ( addAStar, 1000, false );
 
			for ( var i = 0; i < 50; i++ )
			{
				addAStar( true );
			}
		}
 
		private function addAStar ( BPopulate:Boolean ) : void
		{
			var Star:Starlight = new Starlight ();
 
			if ( BPopulate )
			{
				Star.y = Math.floor ( Math.random() * stage.stageHeight );
			}
			else
			{
				Star.y = -20;
			}
 
			Star.x = Math.floor ( Math.random() * stage.stageWidth );
			mcStarContainer.addChild(Star);
 
			for ( var i = 0; i < mcStarContainer.numChildren; i++ )
			{
				if ( mcStarContainer.getChildAt( i ).y > 400 )
				{
					mcStarContainer.removeChildAt(i);
				}
			}
		}
 
		private function keyDownHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = true;
				break;
 
				case 38:
				bUpKeyDown = true;
				break;
 
				case 39:
				bRightKeyDown = true;
				break;
 
				case 40:
				bDownKeyDown = true;
				break;
			}
		}
 
		private function keyUpHandler ( KBE:KeyboardEvent ) : void
		{
			switch ( KBE.keyCode )
			{
				case 37:
				bLeftKeyDown = false;
				break;
 
				case 38:
				bUpKeyDown = false;
				break;
 
				case 39:
				bRightKeyDown = false;
				break;
 
				case 40:
				bDownKeyDown = false;
				break;
			}
		}
 
		private function onEnterFrameHandler ( E:Event ) : void
		{
			if ( bLeftKeyDown )
			{
				if ( nSpeedX > -10 )
				{
					nSpeedX -= nPower;
				}
			}
 
			if ( bUpKeyDown )
			{
				if ( nSpeedY > -10 )
				{
					nSpeedY -= nPower;
				}
			}
 
			if ( bRightKeyDown )
			{
				if ( nSpeedX < 10 )
				{
					nSpeedX += nPower;
				}
			}
 
			if ( bDownKeyDown )
			{
				if ( nSpeedY < 10 )
				{
					nSpeedY += nPower;
				}
			}
 
			GameShip.x += nSpeedX;
			GameShip.y += nSpeedY;
 
			nSpeedX *= nFriction;
			nSpeedY *= nFriction;
 
			if ( nSpeedX * nSpeedX < .001 )
			{
				nSpeedX = 0;
			}
 
			if ( nSpeedY * nSpeedY < .001 )
			{
				nSpeedY = 0;
			}
 
			if ( GameShip.x +