An Introduction to HaxeFlixel with HTML5

A framework to make videogames

A talk by Ciro Durán / @chiguire
London Haxe Meetup, July 2017
Find these slides at http://www.ciroduran.com/talks/flixelmeetup2017
These slides have speaker's notes, use s to bring them up.

Today's Agenda

  • Install HaxeFlixel
  • Create a HaxeFlixel project. See its structure
  • Learn about states, sprites and groups
  • Use FlxG frontends
  • Collisions
  • Timers and Tweens
  • Tilemaps
  • Input with HaxeFlixel
  • Add-ons and more

A Haxe primer...

Haxe is...

  • ...the language
  • ...and also the compiler
  • The Haxe language compiles for a target: cpp, html5, swf, php, lua, etc.
  • The Haxe Toolkit also has haxelib, a command line package manager

Some Haxe constructs


// look, ma, no type declarations
var my_little_str = "ohlala"; 
// you can't do this to a string, compiler will issue an error
my_little_str += 10;
						

for (i in [0...10]) { // no way to do (i = 0; i != 10; i++)
						

// You don't need to cast to Int when reading the array
var my_little_array = [1, 2, 3, 4];

// Macros allow cool stuff like rox-i18n. rox-i18n scans calls
// to strings like this and produces an xml for localising them
var localised_hello = "¡hola mundo!".i18n();
// produces this


  
    hello world!
  

Other Haxe constructs


var str_to_init = if (the_truth_is_out_there) { 
  "I want to believe";
} else { 
  "Trust no one"; 
};
						

enum Color { RED; GREEN; BLUE; RGB(r:Float, g:Float, b:Float); }
// works wonderfully with switch
var color_as_string = switch (color) {
  case RED: "red"; // break is not needed, no fall through
  case BLUE: "blue";
  case GREEN: "green";
  // pattern matching!
  case RGB(r,g,b): "r:"+Std.string(r)+",g:"+Std.string(g)+",b:"+Std.string(b);
}

typedef SomeData = {
  name : String,
  age : Int,
};

Developing for Haxe

Installing HaxeFlixel

In one line:


C:\> haxelib install 
       flixel            # The core framework 
       flixel-tools      # flixel command line tool 
       flixel-templates  # project templates 
       flixel-addons     # very useful, but not core stuff 
       flixel-demos      # code samples
       flixel-ui         # UI library
C:\> haxelib run lime setup
C:\> haxelib run flixel-tools setup
						

Creating a project from a template


C:\workspaces> flixel tpl -n "MyAwesomeProject"
						

Or if you don't have flixel.bat in your path:


C:\workspaces> haxelib run flixel-tools tpl -n "MyAwesomeProject"
						

HaxeFlixel project structure

FlxGame

A Blank FlxState

A Non-blank FlxState

FlxSprite, FlxGroup, and Assets

Initialise Sprites


var sprite = new FlxSprite(100, 10);
sprite.makeGraphic(50, 50, FlxColor.BLUE);
add(sprite);
						

var sprite = new FlxSprite(100, 10, "assets/mysprite.png");
add(sprite);
						

var sprite = new FlxSprite(100, 10, AssetPaths.mysprite__png);
add(sprite);
						

var sprite = new FlxSprite(100, 10);
sprite.loadRotatedGraphic("assets/box.png", rotations, frame, 
	antialiasing, autobuffer);
// rotations == 16, frame == -1, antialiasing == false, 
	autobuffer == false
add(sprite);
						

A Sprite strip

Sprites by Kenney.nl, free to use.

Sprite Animation


var sprite = new FlxSprite(100, 10);
sprite.loadGraphic(AssetPaths.female__png, isAnimated, 80, 110);
sprite.animation.add("idle", [13]);
sprite.animation.add("stand-right", [18]);
sprite.animation.add("stand-left", [18], 10, true, true);
sprite.animation.add("walk-right", [22, 23], 10);
sprite.animation.add("walk-left", [22, 23], 10, true, true);
add(sprite);
						

You may call these as part of class constructor instead for better separation of responsibilities.

Sprite Animation


class Character extends FlxSprite {
  public function new() {
    super(0, 0);
    loadGraphic(AssetPaths.female__png, true, 80, 110);
    animation.add("idle",        [13]);
    animation.add("stand-right", [18]);
    animation.add("stand-left",  [18],     10, true, true);
    animation.add("walk-right",  [22, 23], 10);
    animation.add("walk-left",   [22, 23], 10, true, true);
  }
}
						

Using Groups


// with some sprites created beforehand, named sprite1, sprite2...
var group = new FlxGroup();
group.add(sprite1);
group.add(sprite2);
add(group);
						

Texts


// import flixel.text.FlxText and flixel.util.FlxColor
var title = new FlxText(10, FlxG.height / 5 * 2, // x, y
                        FlxG.width - 20,         // width
                        "Hello world!",          // text
                        36);                     // font size
title.alignment = FlxTextAlign.CENTER;
title.color = FlxColor.MAGENTA;
add(title);
						

FlxG

  • FlxG.log
  • FlxG.watch
  • FlxG.html5
  • FlxG.random
  • FlxG.sound
  • (among others...)

Collisions


FlxG.collide(?ObjectOrGroup1 : FlxBasic, 
             ?ObjectOrGroup2 : FlxBasic, 
             ?NotifyCallback : Dynamic -> Dynamic -> Void
            ) : Bool
// examples
FlxG.collide(character, enemies); // a sprite against a group
FlxG.collide(pigeons, seagulls); // a group against a group
FlxG.collide(boxes); // members of a group against themselves

Overlap


FlxG.overlap(?ObjectOrGroup1 : FlxBasic, 
             ?ObjectOrGroup2 : FlxBasic, 
             ?NotifyCallback : Dynamic -> Dynamic -> Void, 
             ?ProcessCallback : Dynamic -> Dynamic -> Bool
            ):Bool
// FlxG.collide is FlxG.overlap with the ProcessCallback parameter 
// set to FlxObject.separate()
						

FlxTimer


var timer = new FlxTimer();
timer.start(time, 
            function(t:FlxTimer) { 
                trace("I'm complete!"); 
            }, 
            loops
           );
						

FlxTween


FlxTween.tween(a_sprite, {alpha: 0}, time, tween_options);
// Tween options typedef
typedef TweenOptions = {
	?type:Null,
	?ease:EaseFunction,
	?onStart:TweenCallback,
	?onUpdate:TweenCallback,
	?onComplete:TweenCallback,
	?startDelay:Null,
	?loopDelay:Null
}						

FlxTween.num(...); // Tween numbers, easing functions included
FlxTween.angle(...);
FlxTween.color(...);
FlxTween.linearMotion(...);
FlxTween.quadMotion(...);
FlxTween.circularMotion(...);
FlxTween.linearPath(...);
						

FlxTilemap


tilemap = new FlxTilemap();
tilemap.loadMapFrom2DArray( // also from Array or from CSV
  [
    [0, 1, 2, 3, 4, 5], 
    [1, 2, 3, 4, 5, 6]
  ], 
  AssetPaths.platformerPack_industrial_tilesheet__png,
  70, // frame width
  70  // frame height
);
add(tilemap);
						

Result

Input

  • FlxG.keyboard
  • FlxG.mouse
  • FlxG.touches
  • FlxG.gamepad

An example


// import flixel.input.keyboard.FlxKey;
public function inputKeys()
{
  velocity.x = 
    if (FlxG.keys.anyPressed([FlxKey.A]))      { -200; }
    else if (FlxG.keys.anyPressed([FlxKey.D])) {  200; }
    else { 0; };
}

public function detectPause()
{
  if (FlxG.keys.anyJustPressed([FlxKey.P])) { paused = !paused; }
}

Addons and more...

  • In your project.xml, uncomment <!--<haxelib name="flixel-addons" />-->
  • Interfacing with a rigid body simulator, e.g. Nape
  • Effect sprites

Some final criticism...

Questions?

Thanks!

Find these slides at http://www.ciroduran.com/talks/flixelmeetup2017