One of the things that I'm most excited about Luxe are the way that I think it handles States and Scenes.  As I understand it, States will easily allow me to create Finite State Machines for whatever needs them.  So I can drop a States object in my main class to control the game states (menu, pause, play, whatever) or into a Sprite object like a Guard to control its actions (move, attack, search, etc).  

I got some Luxe State Machines working today which I think is going to be the main way that I'm going to structure my games going forward.  I extended the luxe.State object and made a new object called MyState.

My new State Object

 The code is very simple:

  class MyState extends State

{
	var message:String;
	public function new(name:String, message:String) 
	{
		super( {
			name:name
		});
		this.message = message;
	}

	override public function update(dt:Float)
	{
		trace(message);
		return super.update(dt);
	}
}

Basically it takes two parameters.  The first is the name.  This name is important because Luxe stores the states in a Map<String, State> object so I'll be using the name to retreieve them.  The second is a message that I want to trace when the state is running.  This is just for a test to make sure I can tell what is actually working.

Adding the States to the Main.hx

Next I created a States object in my Main.hx ready() function so it is created as the Luxe game is created.  I named it fsm for Finite State Machine, because that's what it is:

fsm = new States();
fsm.add(new MyState("play", "Main: Play"));
fsm.add(new MyState("menu", "Main: Menu"));

Then I set one of the states to run.  In this case, I'm setting the Play state to run.

fsm.set("play");

Then I need a way to swap between states, so I'm going to map keyboard keys specific actions using Luxe.input.  Luxe natively handles this the way that InputHelper (the helper Object that I created for HaxeFlixel)  does. Luxe has the added bonus of allowing mouse clicks and controller buttons to be mapped also (which is something that I never got to), so that is nice.  I'll have to rewrite my screens that let me assign the keys at runtime.

        Luxe.input.bind_key('select', Key.space);
        Luxe.input.bind_key('left', Key.key_a);
        Luxe.input.bind_key('right', Key.key_d);
        Luxe.input.bind_key('jump', Key.key_w);
        Luxe.input.bind_key('stop', Key.key_s);

Now I set Luxe to swap states when I press the 'select' input (that I mapped to the spacebar) in the update loop.

if(Luxe.input.inputpressed('select')) {
	if (fsm.active_states[0].name == "play")
	fsm.set("menu");
	else
	fsm.set("play");
}

Now when I run the app and hit the ~ key to go into debug mode I see Main: Play repeated over and over again.  When I press space, it swaps to Main: Menu.  Success!

Adding States to a Player Object

Next I wanted to test a Finite State Machine on a Player object.  So I created a Player Object by extending a luxe.Sprite object and gave it a public var fsm:States object.  So far nothing exciting.  Then I added some states to it:

mainSprite = new Player( { name:"player" } );
mainSprite.fsm.add(new MyState("run", "Player: Run"));
mainSprite.fsm.add(new MyState("walk", "Player: walk"));
mainSprite.fsm.add(new MyState("jump", "Player: jump"));

I've got three different states assigned to the mainSprite fsm (which actually won't be a finite state machine when I'm done because it will run multiple states simultaneously, so the name is slightly inaccurate but I don't care).  Now I want to allow some inputs to change them around in my update loop.  

if (Luxe.input.inputpressed("left")) {
	mainSprite.fsm.set("walk");
} 
if (Luxe.input.inputpressed("right")) {
	mainSprite.fsm.set("run");
} 

Now when I run my program and press left I see:

Main: Play
Player: Walk
Main: Play
Player: Walk
Main: Play
Player: Walk

My main state machine is still running, but now my mainState state machine is firing off too.  Pressing right gives me:

Main: Play
Player: Run
Main: Play
Player: Run
Main: Play
Player: Run

Now I want to add the jump state to the player that I already defined above, but I want it to run alongside the existing states that mainSprite fsm is running.  

if (Luxe.input.inputpressed("jump")) 
mainSprite.fsm.enable("jump");
if (Luxe.input.inputpressed("stop")) 
mainSprite.fsm.disable("jump");

Now when I press the up key my mainSprite fsm runs both the jump state and whatever other state it happens to be running already.  

Wrapping it up

I'm excited about this.  I like the flexibility that this state system gives me and that it works across objects.  I'm also excited that if I have a GameEntity object or something I can write generic states like a searchState that I can apply to any game object.  

I'm happy with the way that Luxe is working for this.  It is doing exactly what I was hoping it would.  Next up I think I'm going to play around with Scenes.  I think they are going to be essentially like States but applied to graphical objects.  I'm hoping that I can tie States and Scenes together somehow so when I change game states the grahpics will also change. 

Add comment


Security code
Refresh