Polling the keyboard in Actionscript 3

Games often need to get the current state of various keys in order to respond to user input. This is not the same as responding to key down and key up events, but is rather a case of discovering if a particular key is currently pressed.

In Actionscript 2 this was a simple matter of calling Key.isDown() with the appropriate key code. But in Actionscript 3 Key.isDown no longer exists and the only intrinsic way to react to the keyboard is via the key up and key down events.

To rectify this I created the KeyPoll class, which has isDown and isUp methods, each taking a key code as a parameter and returning a Boolean. The class is in my GitHub code repository.

Using the class looks like this

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.ui.Keyboard;
  import net.richardlord.input.KeyPoll;

  public class Test extends Sprite {
    var key:KeyPoll;

    public function Test() {
      key = new KeyPoll( this.stage );
      addEventListener( Event.ENTER_FRAME, enterFrame );
    }

    public function enterFrame( ev:Event ):void {
      if( key.isDown( Keyboard.LEFT ) ) {
        trace( "left down" );
      }
      if( key.isDown( Keyboard.RIGHT ) ) {
        trace( "right down" );
      }
    }
  }
}

The constructor for the KeyPoll class takes a single parameter which is a DisplayObject on which the KeyPoll object should listen to keyboard events. To listen globally to all keyboard input this should be the stage, as in the example.

The class uses a ByteArray to hold the current keyboard state, which is updated in response to Keyboard events and queried by the public methods, isDown and isUp. Using a ByteArray is more compact than using an Array of Booleans, and in tests it also turned out to be marginally faster, although the difference in speed was not significant enough to matter.

Further, the class clears the key state array when the deactivate event occurs, so key state is not retained if the Flash Player loses focus and stops receiving keyboard input.

Physics for Flash Games: Slides

It was great to see so many people at my presentation yesterday at LFPUG. The presentation seemed to go down very well and I had a great evening. Here’s the slides from my presentation. If you weren’t there, they may not make a lot of sense without my talking over the top of them, but I suspect lots of people who were there want to look at the code again.

The presentation is driven entirely from the keyboard arrow keys – left and right to move through the slides and up and down to scroll the text in the code displays.

Click here for the slides (flash required)

Physics for Flash Games

On Thursday this week, I’m doing a presentation on Physics for Flash Games at the London Flash Platform User Group. It’s a tricky presentation to plan because there’s such a wide range of knowledge and ability among the audience but I think I’ve come up with a presentation that has something for everyone. Hope to see lots of London Flash users there. There’s no membership requirement so if you’re interested just turn up. Or better still sign up on the web page because then you have a chance to win one of the prizes in the raffle.

The slides from this talk are now online here.

Casual Multiplayer Gaming

Until recently I wasn’t sure if casual multiplayer gaming was possible. In my experience, multiplayer gaming required a serious investment of time and energy. Even with the simple multiplayer flash games you have to choose a user name, set some options, read the instructions (I don’t want to look stupid in front of the other players), choose a room in the lobby and then ask to play with some one or more other people. At which point I often wonder, since I’ve not played the game before and so am probably rubbish at it, will they wish they’d said no when I asked to play with them?

But I spent most of yesterday afternoon playing Zwok, a multiplayer game that is so simple, and so much fun, I figure there may be something to learn from it. (And if I do learn from it I won’t have to write off yesterday afternoon as wasted time). So here’s a brief summary of my thoughts so far.

  • Joining the game is very simple – just click the guest button (here called “quick play”) and you’re in.
  • There is no lobby, no decisions to be made, no worrying what others think and if they’ll play with you – having clicked the guest button you are dropped straight into a game. It couldn’t be any simpler – click one button and start playing.
  • The game is played in two teams of three. As a player you’re not totally reliant on your team-mates (as I got better I won some games with little or no help from my team-mates) so it really doesn’t matter how bad you are when you start out.
  • The game play is very simple – throw stuff at the other team. We all understand that and have enough experience with gravity in the real world to figure out roughly where our chosen missile will land.
  • Games last between two and five minutes, so it’s perfect to slot a few games in at lunchtime.
  • Registered users get to design their own character, build a reputation and gain access to some additional styles of missiles, but the game-play and fun are not limited for unregistered users.

So, in a nutshell, make it as simple as possible to start playing. I know we apply that to single player casual games too but I’ve not seen it applied so effectively to a multiplayer game before. Add to that the standard “make it fun” and “make it short” and it sounds like a recipe for a successful casual multiplayer game.

Finally, one sour note in the game – who thought it would be a good idea to show the message “You have been kicked out of the game for poor performance” when your network connection is too slow or unreliable? I can’t be the only one to have thought the other players had decided I wasn’t good enough to play with them.

Finite State Machines for AI in Actionscript

A few months ago I said I’d post about the AI in Stick Sports Soccer. Here, at last, is the first such post looking at the code used to implement the Finite State Machines in this and other games I’ve developed.

(For an introduction to Finite State Machines, try Wikipedia and AI-Depot.)

Often finite state machines are implemented (in real projects and tutorials) as a mass of code in a single class, usually a giant switch statement hundreds or (in one instance I’ve seen) thousands of lines long. A simple switch statement is great for a simple agent with two or three states, but the more complex the agent gets, both in the number and complexity of the states, the more complex the code gets. Using a switch statement also offers very little opportunity to reuse code across different agents and different projects (other than by cutting and pasting).

The solution I’ve used in a number of projects is to implement each state as a separate class. The class will contain all the code necessary for entering, updating and exiting that state and nothing else. This way, the code for each state is separate and the agent code isn’t cluttered by it.

In this solution, each state implements the State interface, which looks like this.

interface State
{
    public function Enter():Void; // called on entering the state
    public function Exit():Void; // called on leaving the state
    public function Update( time:Number ):Void;
                   // called every frame while in the state
}

Each state implements Entry and Exit methods for one-off actions that the agent takes when entering and leaving the state, in addition to the Update method which is run repeatedly while in the state. The time paramater in the Update method is the duration of the frame we’re executing.

A couple of states for a patrolling guard in a shoot ’em up might look like this.

// patrolling the area
class Patrol implements State
{
    private var fsm:StateMachine;
    private var guard:Guard;
    
    public function Patrol( g:Guard )
    {
        guard = g;
        fsm = guard.GetStateMachine();
    }
    
    public function Enter():Void
    {
        // check the gun is loaded
        guard.Reload();
    }
    
    public function Exit():Void
    {
    }
    
    public function Update( time:Number ):Void
    {
        guard.FollowPatrolPath( time );
        var threat:Soldier = guard.Threatened();
                               // returns null if no threat
        if( threat )
        {
            fsm.ChangeState( new Attack( guard, threat ) );
        }
    }
}
// attacking an enemy
class Attack implements State
{
    private var fsm:StateMachine;
    private var guard:Guard;
    private var enemy:Soldier;
    
    public function Attack( g:Guard, e:Soldier )
    {
        guard = g;
        fsm = guard.GetStateMachine();
        enemy = e;
    }
    
    public function Enter():Void
    {
    }
    
    public function Exit():Void
    {
    }
    
    public function Update( time:Number ):Void
    {
        guard.ShootAt( enemy );
        if( enemy.IsDead() )
        {
            fsm.ChangeState( new Patrol( guard ) );
        }
    }
}

I then create the Finite State Machine as a class that is responsible for managing the current state. A simple state machine looks like this.

class StateMachine
{
    private var currentState:State;
    
    public function StateMachine()
    {
        currentState = null;
    }
    
    // Update the FSM. Parameter is the frametime for this frame.
    public function Update( time:Number ):Void
    {
        if( currentState )
        {
            currentState.Update( time );
        }
    }
    
    // Change to another state
    public function ChangeState( s:State ):Void
    {
        if( currentState )
        {
            currentState.Exit();
        }
        currentState = s;
        currentState.Enter();
    }
}

The agent then uses an instance of the StateMachine class to handle its AI.

class Agent
{
    private var fsm:StateMachine;
    
    public function Agent()
    {
        fsm = new StateMachine();
    }
    
    public function Update( time:Number ):Void
    {
        fsm.Update( time );
    }
    
    public function GetStateMachine():StateMachine
    {
        return fsm;
    }
}

The agent class is a lot more manageable without the state machine implementation and all the states inside it, and I have a single StateMachine class that can be used by all agents. I can even share states across agents too.

Finally, I add a number of features to the StateMachine class to allow chaining of states and returning to previous states.

class StateMachine
{
    private var currentState:State;
    private var previousState:State;
    private var nextState:State;
    
    public function StateMachine()
    {
        currentState = null;
        previousState = null;
        nextState = null;
    }
    
    // prepare a state for use after the current state
    public function SetNextState( s:State ):Void
    {
        nextState = s;
    }
    
    // Update the FSM. Parameter is the frametime for this frame.
    public function Update( time:Number ):Void
    {
        if( currentState )
        {
            currentState.Update( time );
        }
    }
    
    // Change to another state
    public function ChangeState( s:State ):Void
    {
        currentState.Exit();
        previousState = currentState;
        currentState = s;
        currentState.Enter();
    }
    
    // Change back to the previous state
    public function GoToPreviousState():Void
    {
        ChangeState( previousState );
    }
    
    // Go to the next state
    public function GoToNextState():Void
    {
        ChangeState( nextState );
    }
}

Which leads to modified and new classes like the following.

class Soldier extends Agent
{
    ...
}
class Guard extends Soldier
{
    ...
}
// attacking an enemy
class Attack implements State
{
    private var fsm:StateMachine;
    private var self:Soldier;
    private var enemy:Soldier;
    
    public function Attack( s:Soldier, e:Soldier )
    {
        self = s;
        fsm = self.GetStateMachine();
        enemy = e;
    }
    
    public function Enter():Void
    {
    }
    
    public function Exit():Void
    {
    }
    
    public function Update( time:Number ):Void
    {
        self.ShootAt( enemy );
        if( enemy.IsDead() )
        {
            fsm.GoToPreviousState();
        }
    }
}
// wait for a given period of time then go to next state
class Wait implements State
{
    private var fsm:StateMachine;
    private var self:Agent;
    private var waitTime:Number;
    private var timeRemaining:Number;

    public function Wait( s:Agent, t:Number )
    {
        self = s;
        fsm = self.GetStateMachine();
        waitTime = t;
    }
    
    public function Enter():Void
    {
        timeRemaining = waitTime;
    }
    
    public function Exit():Void
    {
    }

    public function Update( time:Number ):Void
    {
        timeRemaining -= time;
        if( timeRemaining < 0 )
        {
            fsm.GoToNextState();
        }
    }
}

Having used this solution for a couple of years I can't imagine returning to the mess of giant switch statements, even for the simplest projects. And I use the same state machine, agent base class and many of the states themselves across multiple projects, which speeds up development time.

Addendum 2011

There's an Actionscript 3 version of this in my Github repository.