Dev Log #8: Player is now “controllable”

These days I’ve been very busy on my previous project, Zombie Incident. Nintendo of Europe has approved it and I had to work on the marketing materials: trailer, banners, screens,…

This doesn’t mean I’ve haven’t advanced on Maria Akane!

As I announced previous week, I’ve been working on the Animation controller of the main character.

I created a decoupled component that examines flags (input) and changes from one state to another depending its predefined transitions. In fact, the animation controller is a class which manages several specific animation controllers, one per each animation “layer”. The cool thing here is the way we manage these layers to provide animation feedback to the player.

For instance, if the player is walking, we see the animations in the Side Layer in action. The same applies when he is idle, crouch, crouch-walking, and jumping. But what happens if we attack? Instead of having to create an animation for attacking and walking, attacking and idle, and so on, we mix the Side Layer with the Attack Layer in a special way.

game-controls

One of the coolest features is the blending between animations I’ve implemented for this system, which also blends the Attack Layer with the Side Layer when the attack animation finishes.

As I told on last post, I’ve used QFSM to design the animation controller. And after it’s designed, I that data to generate c++ code! Sounds weird, doesn’t it?

Qfsm - AnimController-platformer_side.fsmThis is the state machine for the layer who manages the side animations. And this is part of the code it generates :

...
typedef struct
{
    char* m_szExpression;
    uint  m_uiFlagsValues;
    uint  m_uiFlagsMask;
    float m_fBlendTime;
}TTransitionData;
//-------------------------------------------------------------------
static TTransitionData gsoTransitions[13] =
{
    {"",0,0,0.0f},
    // 1
    {
        "WALK",
        0 | ACV_WALK,
        0 | ACV_WALK,
        0.250
    },
    // 2
    {
        "CROUCH",
        0 | ACV_CROUCH,
        0 | ACV_CROUCH,
        0.250
    },
...
//------------------------------------------------------------------
enum EAnimControllerState
{
    ACS_NONE,

    ACS_IDLE,
    ACS_JUMP_UP,
    ACS_JUMP_DOWN,
    ACS_WALK,
    ACS_CROUCH,
    ACS_WALK_CROUCH,

    ACS_NUM_STATES,
    ACS_MAX_STATES = 0xffffffff
};
//------------------------------------------------------------------
static int gsiStateTable[ACS_NUM_STATES*ACS_NUM_STATES] =
{
    -1,0,-1,-1,-1,-1,-1,
    -1,-1,3,-1,1,2,-1,
    -1,-1,-1,4,-1,-1,-1,
    -1,5,-1,-1,6,-1,-1,
    -1,9,7,-1,-1,-1,8,
    -1,11,-1,-1,-1,-1,10,
    -1,-1,-1,-1,12,13,-1,
};
...

With this, player is now “controllable” so I can start developing other gameplay elements and mechanics.

Taking in consideration this has been a rather techical post, I’ve tried to be as brief as possible so… that’s it!

This entry was posted in Blog. Bookmark the permalink.

Comments are closed.