OKay, here's the next part of the tutorial!
III: Creating the Menu:Now that we have your project starting properly, it's time to move on to making your first State - specifically a FlxState for your main Menu.
Before we jump into creating a state we should first explain what a state is used for. States are Classes that are used primarily as central control points for the different portions of your game. They handle the creation of new drawing surfaces, adding in game objects, changing scores, displaying menus, etc.
In this tutorial we are going to create two basic states. The
MenuState, and the
PlayState. The MenuState we will use to create a simple menu for the game, and the PlayState will house all of the logic for object creation, score keeping, and collision checking.
 | Programming Tip: |
| You can kind of think of States as separate race-tracks that are adjacent to each other. When the player starts the game, they will start on the MenuState track, and they will drive around and around in circles on that track. When we switch to the PlayState, they will teleport over to the PlayState track, which is larger and has more checkpoints and obsticles than the MenuState. When the player dies or quits the game, they get teleported back to the MenuState track, until they want to start playing again. You can have a large number of different states for your game, if you want - you can have a menu state, a load screen state, the game state, an inventory state, etc.
If any of this confuses you, you will feel better once we dig in and start going over the states. If at the end you are still confused, consume the pill that comes with this tutorial, and everything will feel much better. |
The Menu State1: Since you already created a new class named MenuState earlier, FlashDevelop has created the basic framework for you. Open up this file now, and you'll see the following:
package
{
public class MenuState
{
public function MenuState()
{
}
}
}
2: Like all AS3 classes you will want to define your package and import any classes you will need, so change the first part to look like this:
package com.Tutorial
{
import com.adamatomic.flixel.*;
3: Next, we want this class to extend FlxState. Remember extending a class that you imported allows your to make a new Class based off of the one you are extending. Change
public class MenuState
to say:
public class MenuState extends FlxState
4: Next, we need to define our Constructor. Now, in this case, because we are using this State as a Menu, we want to 'take over' the Constructor function for FlxState entirely. To do this, replace
public function MenuState()
{
with this:
override public function MenuState():void
{
5: Next, we're going to display the name of our game on the Menu, with something that tells the player how to start the game. When you have a better grasp of using Sprites, sounds, and special effects, you can put a logo or something else on the menu screen. For now, we'll just use the FlxText Class. Within the MenuState Constructor, add this code:
this.add(new FlxText(0,(FlxG.width/2) - 80, FlxG.width, 80, "Flixel Tutorial Game", 0xffffffff, null, 16,"center")) as FlxText;
Lets take a look at what this is doing.
First, "this.add()" is essentially saying "take something and attach it to 'this'". "This" is sort of a shortcut to refer to the current object in AS3. In our case, "This" refers to the instance of MenuState that is currently open and running through this Constructor.
Now, we're also passing it an object. The "new FlxText()" is going to create a new FlxText object. We're going to pass it some parameters, and then our new FlxText object is going to be attached to our MenuState.
By looking up the FlxText Class and it's constructor in the
Documentation, we can see what parameters it's expecting:
function FlxText (X : Number, Y : Number, Width : uint, Height : uint, Text : String, Color : uint, Font : String, Size : uint, Justification : String, Angle : Number)
We're passing: 0,(FlxG.width/2) - 80, FlxG.width, 80, "Flixel Tutorial Game", 0xffffffff, null, 16,"center", which should place our text, "Flixel Tutorial Game", in white, at the center of the screen (roughly).
6: Lets also tell the player how to start the game. In a new line right under our other text, add:
this.add(new FlxText(0, FlxG.height -24, FlxG.width, 8, "PRESS X TO START", 0xffffffff, null, 8, "center"));
This should add the text "PRESS X TO START" near the bottom of the screen in white, and in a smaller point size. That's all we want to do in MenuState's Constructor.
7: We now need to tell the game what to do each time it 'updates'. Most programs have some sort of system loop that is always running while the program is running - usually a large number of iterations per second. This loop, in its simplest form, goes something like this:
Start:
wait for something to happen
Go back to start
In our case, Flixel's game loop is mostly going to be handling a lot of stuff for us, so we won't have to worry about it, but we do want to be able to do things while this loop is running, so we use the "update" function.
Essentially, Flixel is going to call "update" every loop iteration, and we can choose to have things happen within the update function if we want. For the MenuState, we're simply going to wait for the Player to press X. Add this code after the Constructor, and before the last "}" in the class:
override public function update():void
{
if (FlxG.kA)
{
FlxG.flash(0xffffffff, 0.75);
FlxG.fade(0xff000000, 1, onFade);
}
super.update();
}
We're adding a whole function at once, but don't worry, it's pretty simple.
First, we're going to "override" the "update" function that's in FlxSprite - this means that instead of FlxSprite's update being called, we're saying "use MenuSprite's update instead".
Next, we ask if FlxG.kA is True or not. FlxG is Class in Flixel that handles a lot of general pieces all at once. kA is a variable that tracks wether or not the "A" Key is pressed or not (in Flixel, the "A" key is "X" on the keyboard, and the "B" key is "C"). Whenever the player has pressed the "A" key, FlxG.kA is going to be True. When the player lets go of the key, kA will be False.
So, we're asking "is FlxG.kA True?" if it is, ie, the player has pressed the letter X on their keyboard, we're going to perform the next section of code.
Regardless of if kA is true or not, we're going to call the "super.update()" function, which basically says: "now call the "update" function of whatever class I'm extended from".
So, if X is pressed, and kA is true, then we're going to do two things.
 | First, we're going to call the FlxG "flash" function, which is going to flash the color white on the screen, then we're going to fade to black, via the "fade" function. |
 | When the fade is complete (which should take 1 second), we're going to call the "onFade" function, which we'll write next. |
8: Underneath the constructor, we add a new function:
private function onFade():void
{
FlxG.switchState(PlayState);
}
This function will be called after the fade command is finished. All it will do is switch the current state from MenuState to PlayState.
9: We can go ahead and create the PlayState file - add a new Class file to your com/tutorial folder, and name it PlayState.as.
So, lets review: when the player starts the game, its going to initialize itself and then enter the MenuState:
 | When the MenuState loads, its going to put the text on the screen and then wait for the player to press the A button (X on the keyboard). |
 | Once the player presses the button, it will Flash white, then fade to black. |
 | As soon as it finishes fading, it's going to switch the game's state from MenuState to PlayState - which will be where all our game logic is. |
Make sense?
If you try out your game now, you'll be able to see the menu come up, and flash/fade when you press X. After that will be an error because we haven't finished with the PlayState yet... we'll get to that in the next section.
So your MenuState.as file should look like this:
package com.Tutorial
{
import com.adamatomic.flixel.*;
public class MenuState extends FlxState
{
override public function MenuState():void
{
this.add(new FlxText(0, (FlxG.width / 2) - 80, FlxG.width, 80, "Flixel Tutorial Game", 0xffffffff, null, 16, "center")) as FlxText;
this.add(new FlxText(0, FlxG.height -24, FlxG.width, 8, "PRESS X TO START", 0xffffffff, null, 8, "center"));
}
override public function update():void
{
if (FlxG.kA)
{
FlxG.flash(0xffffffff, 0.75);
FlxG.fade(0xff000000, 1, onFade);
}
super.update();
}
private function onFade():void
{
FlxG.switchState(PlayState);
}
}
Stay tuned for the next part where we discuss the PlayState, and creating your Sprites!