Flash Tutorial Links:
Play Games: HTML5 Tutorials:

How To Make A Simple Flash Game

A catcher kind of game is probably the easiest flash game you should start developing on this learning journey. Every flash gaming site you go to, I'm pretty sure you can find a similar kind of [insert object here]-is falling-from-the-sky-and-you-need-to-catch-it kind of game.

Apple Catcher game

This will be the first flash game tutorial that we'll learn with. The game is simple to make and I'll use it to highlight some basic fundamentals and show you the framework to follow when making a flash game.

Game Scenario

The scenario of this flash game tutorial is simple. It's harvest time for the famous Red Apples! Jovia (the blue creature) loves eating apples and the enchanted forest he lives in is full of them. During harvest time, they fall onto the ground in large amounts. Unfortunately, their tender apple skin provides little protection when they fall, and they splatter into pieces upon contact with the forest bed.

Help Jovia snack on them before they drop to the ground. It always tastes better crunching on an entire apple for Jovia!

Game Details

  1. Jovia follows the movement of the player's mouse cursor
  2. Each apple drops randomly with a constant speed from the top
  3. Each apple disappears when they touch the ground
  4. Each apple that Jovia eats earn the player 10 points

Download the Game Files

The files you need to create this game can be downloaded from here.

Step 1 - Managing your FLA file

I would always start off with the fla file, because it sets the stage for the game. In this simple flash game tutorial, we just need 1 frame for the entire game. Eventually, we'll move on to a more complex setup than this by using more frames... but let's leave that to another day.

Although we will only use 1 frame, I like to use different layers to keep track of my game assets. Here is my recommended setup. If you check out other flash game tutorials, they all tend to be a little haphazard in the game structure. There are tons of flash game tutorials here, and I will code in a very similar fashion, so you can expect a great deal of consistency.

flafile

The 3 layers UI, Contents and Background are self-explanatory. Use them to layer your different game assets. In a more complex game environment, you may want to handle all these aspects in your game files directly. Since these are fairly simple games that we're writing here, this framework allows you to get things done fast.

In this short flash game tutorial, the UI layer contains a TextField which we will use for displaying of the score to the player. We set the name of this textfield as txtScore. Later on, the flash game will reference this textfield to reflect the latest score to the player.

The Contents layer stores the mcGameStage where the flash game will take place. Notice that we're using this separate MovieClip called mcGameStage to let all the action take place. In a way, you'll see the benefits later on where we need to scroll things, or remove the game elementas totally. It will work better than if you were to load everything onto the stage itself. The Background layer stores a simple background behind the game's stage.

The AS layer contains all the actionscript you need in that frame. There shouldn't be any movieclips or art assets placed here, and keep the Actionscript simple here; remember that we already have the GameController.as taking care of the complex game logic for us.

And truly, these are the code that we need to put in that frame only.

flafile2

"What?", you may say. Only 1 line of code? Yup. This is the only line of code you need to put into your FLA file for now. It calls the function startGame which we'll define later on in the GameController.as file. Just a caution again, that if you're unfamiliar with AS3 coding, please pick up a book and learn it first. You do not need to be an expert at it, but basic familiarity with the syntax is required.

Take a look at your library assets now. You should see the following assets.

libraryassets

I'm never a fan of managing library assets using the Flash IDE, and this is one area where I hope Adobe can improve in. Organising these assets can be quite a pain, especially when the flash game is huge. CS4 made it a little easier by allowing you to search. To facilitate your keeping track of the flash game assets, I recommend you use a folder structure, and number them accordingly so that the folders will always be in the sequence you wanted them to be at.

Keep the raw png or jpeg files in a separate folder ( I call it 00.RAW ). Your main interaction in the game will be with the movieclips and sprites. As you can see, there are 3 movieclips now, GameStage, Apple and Jovia herself. To be able to add Jovia and Apple objects into the game dynamically, you need to make it into a class. Fortunately, you do not have to write the codes for all classes. Flash defaults it if it is unable to find a class file written by you for that movieclip. In this case, the default ones will suffice.

Right click on Jovia, and choose Properties. Under the Linkage portion, you should set the following.

linkage

By setting Jovia as the name of the class, you can subsequently create a Jovia object by instantiating it in your actionscript (you'll see it below in GameController.as) Set the base class as flash.display.Movieclip. This way, Jovia will inherit the properties of a movieclip in Flash.

Likewise, do the same for the Apple MovieClip. There is no need to create the Linkage for GameStage since we will be dragging it directly onto the Stage during design time instead of runtime.

Step 2 - Setting initial values in your GameController.as

Once you are done with the FLA file, let's focus on the GameController.as. Like I said, this is the soul of your game. Remember to check that you have set the Document class of your FLA file to point to the GameController.as file.

document class

We'll be doing most of our ActionScript coding in the GameController.as. If you need an explanation for lines 1 to 38 where we import modules in and set the variables, please head over to the tutorial on Game Framework where I explain those in greater details. Otherwise, in each tutorial, we'll focus solely on the code that makes each particular game work and not spend too much time revisiting those concepts.

Now, if you look at line 40 to 43, you'll see that the constructor is actually empty. There'll be cases where we probably have to fill the constructor up with some code, but in this case, it isn't necessary. But because in Object Oriented Programming, the constructor function is such an important function, I'll just leave it here in case seasoned programmers start to wonder what happened to it.

40
41
42
43
public function GameController()
{
    
}

The startGame function is where you initialize all the variables and game states that your game should be defaulted to. Recall that this is the single line of code we placed in the action layer in our FLA file. That line of code actually triggers this function here.

45
46
47
48
49
50
51
52
53
54
55
public function startGame()
{
    speed = C.PLAYER_SPEED;
    gravity = C.GRAVITY;
    score = C.PLAYER_START_SCORE;
    randomChance = C.APPLE_SPAWN_CHANCE;
    apples = new Array();
    player = new Jovia();
    mcGameStage.addChild(player);    
    mcGameStage.addEventListener(Event.ENTER_FRAME,update);
}

You can see that this is where I use values from the constants file, C.as extensively. As we discussed earlier on, we could have very well used speed = 5 instead of speed = C.PLAYER_SPEED in line 47. But using constant values is a good practice that you should cultivate. It enables you to change game mechanics easily without having to search through and fiddle with your code too much. This flash game tutorial, as well as most of my others, will make use of this concept extensively.

In line 52, we create a Jovia object, which is the player controlled character. Recall earlier on that although we didn't write the class for Jovia, we have used the default Flash class file for it by setting it in the linkage. But simply by creating it in line 52 will not cause Jovia to appear at all. It still creates it and places it on the stage, but it will not be visible to the player.

Line 53 is where we add the player object onto the mcGameStage (which is the MovieClip on stage where all the game action will take place). Only with this will Jovia appear visible to the player when you run the game.

Line 54 is where you set the function, update, to run as many times as specified by the fps of your FLA file. Hence, the update function is essentially your game loop.

Step 3 - The Game Loop, Handling User Controls

Earlier on, we talked about the game loop, and that it has 3 key elements to it. These elements are user control, game logic and display.

We'll take a look at how to handle the user control first. Recall that this function update will run as many times a second as you have set previously as the fps of your FLA file.

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
78
79
80
81
82
private function update(evt:Event)
{
    //******************			
    //Handle User Input
    //******************
    var currMouseX = mouseX;
    var currMouseY = mouseY;
    var moveX = 0;
    var moveY = 0;
    if (currMouseX > player.x)
    {
        moveX = 1;
    }
    else if (currMouseX < player.x)
    {
        moveX = -1;
    }
    if (currMouseY > player.y)
    {
        moveY = 1;				
    }
    else if (currMouseY < player.y)
    {
        moveY = -1;				
    }

This game is purely playable using the mouse, so all you need are mouseX and mouseY which will track your mouse's x and y coordinates on screen. The Flash runtime provides values for the x and y coordinates through these two variables, mouseX and mouseY. We assign them to our own variables, currMouseX and currMouseY which we'll use later on for the rest of the codes.

The logic in the code above is straightforward. moveX and moveY are two variables which we'll use later in the game to track the motion of the player. If moveX is 1, it means that the player should be moving to the right by 1 pixel. If moveX is -1, it means the player should be moving to the left by 1 pixel. Likewise, moveY tracks the movement in the y direction, but do note that for y is actually positive in the downward direction. A value of 1 for moveY moves the player down by 1 pixel.

Line 64 and 65 initializes moveX and moveY to zero first, so that by default, no movement is detected. Line 66 then checks if the mouse position is on the right of Jovia. If it is true, moveX is set to 1, indicating that Jovia should move towards the right.

Line 74 to 82 handles the same movement in the y-axis.

Notice that in this chunk of code, the player does not actually move. This is the purpose of dividing up the game loop into these 3 distinct portions. The code here merely captures the user input. It is up to the next portion which handles the game logic to process these inputs, and react accordingly. If you need some reasons why, you can think of a situation whereby the player is actually trapped and is unable to move. So even though we capture the user input that the player wants to move, when we handle the game logic, we should refuse this motion.

So that's it! That's all the user input that we're going to allow for the game now. In subsequent tutorials, I'll show how key input can be captured.

Step 4 - The Game Loop, Handling Game Logic

Next, let's move on to code for the game logic. Remember that this is essentially the most important part of your game as it crunches the game numbers and churns out the new game state based on all factors in the game. If the coding is not done well here, it could potentially cause unbearable lagging in your game.

After obtaining the user input, we update Jovia's new position.

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//******************
//Handle Game Logic
//******************
//Handle new Player Position
if (moveX > 0)
{
    if (player.x + C.PLAYER_SPEED <= currMouseX)
        player.x += C.PLAYER_SPEED;
}
else if (moveX < 0)
{
    if (player.x - C.PLAYER_SPEED > currMouseX)
        player.x -= C.PLAYER_SPEED;
}
if (moveY > 0)
{
    if (player.y + C.PLAYER_SPEED <= currMouseY)
        player.y += C.PLAYER_SPEED;
}
else if (moveY < 0)
{
    if (player.y - C.PLAYER_SPEED > currMouseY)
        player.y -= C.PLAYER_SPEED;	
}

You can see that based on the moveX and moveY values we set earlier on when we handled the user's input, we update the position of Jovia accordingly. Notice that an additional check is done in lines 89, 94, 99, 104, without which, Jovia will be dancing around your mouse position, which is pretty unsightly. You can try commenting them off to see what happens. By changing the .y and .x properties of the player, we move it around the stage.

Next, we will spawn the apples randomly.

107
108
109
110
111
112
113
114
115
116
117
//Spawn new apples
if (Math.random() < randomChance)
{
    var newApple = new Apple();
    newApple.x = Math.random() * C.APPLE_SPAWN_END_X+C.APPLE_SPAWN_START_X;
    
    newApple.y = C.APPLE_START_Y;
    apples.push(newApple);
    
    mcGameStage.addChildAt(newApple,0);
}

Line 108 first makes a check based on a randomChance you specified earlier on in C.as, the constants file, because Math.random() returns you a number from 0 (inclusive) to 1 (exclusive). If the probability of spawning happens, we just instantiate a new apple by using new Apple() in Line 110. Recall that this is possible because we set the Linkage of the Apple Movieclip earlier on. We then set its respective x and y locations to a random starting x position, but a fixed y position.

In Line 114, we push each newly created apple into an array called apples. We keep track of each apple so that it's easier to keep track of, and interact with them in the game. But remember that instantiating an object or pushing it into an array will not cause it to appear on the stage at all. The player will still not be able to see them, although technically, the game is still interacting with them. To make them show up on the game stage, remember to include Line 116. mcGameStage.addChildAt(newApple,0) will insert the apple at depth 0, which is the bottommost depth. This will ensure that Jovia is always on top on the apples that are falling.

So far so good ... with these code, the apples should be randomly created, but they would all be floating in the air. We need to add in the game logic to pull them onto the ground using simulated gravity.

118
119
120
121
122
123
124
125
126
127
128
//Move Apples
for (var i = apples.length-1; i >= 0; i--)
{
    apples[i].y += gravity;
    
    if (apples[i].y > C.APPLE_END_Y)
    {
        mcGameStage.removeChild(apples[i]);
        apples.splice(i,1);
    }
}

This is one of the main reasons why we added each apple into the array apples just now. We can now easily iterate through the apples array to reference each of the apples that has been created so far. We move each of the apples down by as many pixels as the gravity which we specified in Line 121.

We do not want the apples to keep falling indefinitely, so Lines 123 to 127 will check if the apples have fallen onto the ground and if so, remove them from the game so that the user cannot see them by using the removeChild function in Line 125. Since we do not want to be dealing with that apple anymore (hey! it's contaminated after it touches the ground and Jovia is smart enough to avoid it), remember to remove it from the array apples using the splice function in Line 126.

Over here, we're simulating the game based on a flat gravity, where the apples fall with a fixed velocity. With some code improvements, we'll be able to modify it to move faster as it falls.

Also, notice how we did the for loop in line 119. We start off with the last element in the array, and loop all the way to the first. This is IMPORTANT ! Because we may splice off an apple from within the loop (line 126), we mess up the array index reference if we were to loop through the array from the front. So remember that for such for loops, we always loop from the back.

And now, the last part is to make Jovia interact with the apples ... finally!

130
131
132
133
134
135
136
137
138
139
140
141
142
143
//Check for collision
var playerPoint = new Point(player.x, player.y);
for (var i = apples.length-1; i >= 0; i--)
{
    var applePoint:Point = new Point(apples[i].x, apples[i].y);
    if (Point.distance(applePoint,playerPoint) < C.HIT_TOLERANCE)
    {
        //Register hit
        score += C.SCORE_PER_APPLE;
        
        mcGameStage.removeChild(apples[i]);
        apples.splice(i,1);
    }
}

The good thing about making the player's position into a Point object is because Flash provides the API to calculate the distance between 2 points. In line 131, we create a new point based on Jovia's current position.

I know that many other flash game tutorials out there suggest using hitTestObject function to check if two MovieClips are touching each other. My feel is that the hitTestObject operation lacks control because it checks based on the bounding box. We could otherwise use the hitTestPoint to do the job, but again we either do not require the pixel perfect accuracy it provides or it lacks the kind of control I would want to have in this case. I prefer using the distance function provided in the Point class to get the distance between 2 points (here, the points are the two centres of the apple, and the player), and then comparing if it is lesser than a certain tolerance level.

distance

The diagram above shows you graphically what is happening in line 135. It makes sense to check that if the point to point distance is less than the tolerance level (exaggerated a little in the diagram so that it's easier to visualize). If so, then we consider Jovia as having touched the apple.

So, in the event that a collision occurs, we add a score to the player in line 138. Line 140 removes the apple visually from the stage, and line 141 removes the reference to the apple from our array such that it no longer updates. Eventually, the garbage collection in Flash will remove it totally.

Step 5 - The Game Loop, Handling Display

And finally, the third key element in the game loop would be to display all the necessary information to the player. We should avoid further game changing computations here, and focus mainly on updating the UI display or animations if need be.

145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
//******************
//Handle Display
//******************
//Animate the player
if (moveX > 0)
{
    if (player.currentLabel != C.JOVIA_RIGHT)
        player.gotoAndPlay(C.JOVIA_RIGHT);
}
else if (moveX < 0)
{
    if (player.currentLabel != C.JOVIA_LEFT)
        player.gotoAndPlay(C.JOVIA_LEFT);
}
//Display new Score
txtScore.text = String(score);

Lines 149 to 158 handles the part to animate Jovia into flapping her wings. moveX was set earlier on in the handling of user input. The additional if conditions in line 151 and 156 are checks to see if the animation of Jovia flapping her wings in the respective-facing direction is already playing. If it isn't, then that animation is activated. If these lines were missing, Jovia would look like a video disc that is stuck while playing (as usual, you can comment it off to see the effect).

The line 160 updates the text field in the UI to reflect the latest score. Notice the casting into a String object we have to do on the score variable. This is because score is declared as a Number earlier on, but txtScore.text expects a String.

The Game

And this is the very first game you have created. I hope you see from this flash game tutorial how easy it is to make a simple flash game.

Download the Game Files

The files you need to create this game can be downloaded from here.

How To Play

Objective: Eat all the falling apples.

Controls: Move your mouse cursor to make Jovia follow it.


Content on this page requires a newer version of Adobe Flash Player.

Get Adobe Flash player


Flash Resources
Preloader FPS Display Sounds & Music
Keycodes Name Generator
Game Development Resources
Sprite Sheets