Now that we have covered getting your development environment up and running, we are going to jump into our first HaxeFlixel application. Let’s start from the very beginning and create a new application. As mentioned in the Getting Started tutorial, we can create an application using the simple command:
flixel tpl –n “HelloWorld”
This creates a directory with a skeleton application to get us started. It actually creates a bit more code then we need, we are going to strip it down to just two source files.
It is pretty much tradition to make your first program a simple Hello World application, so that is what we are going to do. We will simply print the text “Hello World” on screen, but since this is ultimately a game we are creating here, we will also animate it! Ok, code time, let’s start with Main.hx, the entry point of our application. Here is the source code:
import flixel.FlxGame; import openfl.display.Sprite; class Main extends Sprite { public function new() { super(); addChild(new FlxGame(0, 0, GameState)); } }
One thing that might immediately seem awkward is that our Main class inherits from Sprite. This is a throwback to the Flash development world, just think of a Sprite as “something that is visible on screen”. When our Main object is created it’s constructor is called and really it does just one thing, creates a new FlxGame object passing our GameState class in as a parameter. The first two parameters to the FlxGame constructor are the width and height of our game window. In this case we didn’t specify a value, meaning the value from the Project.xml file will be used instead. If you look at Project.XML (which was generated for you) you will see the lines:
<!-- ____________________________ Window Settings ___________________________ --> <!--These window settings apply to all targets--> <window width="640" height="480" fps="60" background="#000000" hardware="true" vsync="true" /> <!--HTML5-specific--> <window if="html5" resizable="false" /> <!--Desktop-specific--> <window if="desktop" orientation="landscape" fullscreen="false" resizable="true" /> <!--Mobile-specific--> <window if="mobile" orientation="landscape" fullscreen="true" width="0" height="0" />
Due to this configuration by default our application will have a resolution of 640×480, while on mobile devices we will instead use the full screen. As you can see it’s possible to set multiple definitions using the if=”platform” conditional. If you want to have FlxGame create a larger or smaller window you can either specify the value when creating your FlxGame object, or you can change it’s value in the <window> tag. Ok, back to our code…
As mentioned earlier, we created a FlxGame object, which is the heart of your application and contains the game loop. Every single game or game engine has a game loop in some form, it’s essentially a loop that runs over and over until your game is done and is responsible for polling input, updating the world and drawing graphics on screen. We don’t actually use FlxGame directly however, our game is instead broken into multiple states. We see this in action in GameState.hx, here is the source:
import flixel.FlxG; import flixel.FlxState; import flixel.text.FlxText; import flixel.util.FlxColor; class GameState extends FlxState { var text:FlxText; override public function create():Void { super.create(); text = new FlxText(0,0,FlxG.width,"Hello World",64); text.setFormat(null,64,FlxColor.RED,FlxTextAlign.CENTER); add(text); } override public function update(elapsed:Float):Void { super.update(elapsed); text.y ++; if ( text.y > FlxG.height) text.y = 0 - 64; } }
This is the meat of our application. You will notice that GameState inherits from FlxState. FlxState is a very important concept in HaxeFlixel development. Essentially you break your game logic up into a number of different states, how exactly you do do this is up to you. A common division might be Title Screen State, Game Playing State, High Score State, Game Over State for example. Another option is to break your game up into screens, so instead have it look something like Splash Screen State, Main Menu State, Game Playing State, Game Credits State, etc. Or alternatively you could break your game into levels such as Main Menu, Level One, Level Two, etc. Really it comes down to whatever fits the structure of your application the best. Just keep in mind that FlxState are the logical units for breaking down gameplay complexity into manageable pieces and if you hate the idea completely, no problems, you can just throw everything together into a single state if you prefer.
At the end of the day though, the FlxState is a pretty simple data structure with two primary tasks. First, it contains all the “stuff” that makes up that portion of your game. In this particular example that “stuff” consists of a single FlxText node, but it could contain dozens or thousands of objects. Just realize when we call the add() method, we are adding to a collection of Objects contained in the FlxState class. The second important part of FlxState is to provide a number of callback methods that FlxGame can call. As I said earlier, FlxGame contains our main game loop. Each pass through this loop however it calls a series of functions on the currently active FlxState, the most important of which are draw() and update(). It is through these two callbacks that your FlxState derived class is modified over time. Let’s look back at our example and walk through the code.
First in our create() method, we call our parents constructor so we are properly set up and configured. We then create a new FlxText object, which is a special sprite (aka, something visible on screen) object for displaying text. In this case we display the string “Hello World” at 32px height in the default font. Notice we used a call to FlxG to get the width of the screen. FlxG is a special global helper class containing handy information such as width and height of the screen, the default camera, access to input and more. You can also get read only access to the FlxGame class we created earlier. Once we create our FlxText object, we format the text so it’s aligned in the center and drawn in red. Next we call the add() method, adding the text object to the GameState. Once added it will automatically be drawn every frame unless disabled.
Next we implement the update() method. As mentioned earlier, this is a callback function that is going to be called by FlxGame every pass through the game loop. The one parameter it receives is a Float with the amount of time that elapsed since the last pass through the game loop. This is extremely handy as it enables us to determine just how fast our game is running. In this particular case all we do is update the text object’s y coordinate ( we will talk more about coordinates shortly, don’t worry ) scrolling until our text is off screen, at which case we go back to the top and start all over. Please note that this particular code will run at different speeds depending on how fact the device it runs on is! We will look at ways to make the code run at the same speed on all machines in a future tutorial. For now, when you run this code you should see:
In the next tutorial we will dive a bit deeper into drawing graphics on screen.
The Video