1
\$\begingroup\$

I'm creating a 2D Sidescrolling Action RPG with MonoGame and I am using a finite state machine. A state consists of an animation and some behavior, only one state can be executed at once, however:

If the player is moving left/right and then jumps, or if he's jumping and then moves left/right I want to play a specific horizontal jumping animation while executing the behavior of both states at once. How is this usually handled? Should I make a completely seperate state for this and copy the behaviors over? That doesn't seem right in accordance to the DRY principle.

BTW I'm going to have a lot of similar merge states, so just making an exception this time won't do.

\$\endgroup\$
3
  • \$\begingroup\$ Can you explain me why you are using a finite state machine? What are it's benefits in your scenario? \$\endgroup\$ Commented Jun 27, 2017 at 20:56
  • 1
    \$\begingroup\$ Look at this game patterns book chapter As mentioned below, pushdown automaton could work, or a hierarchical state machine. As @CedricMartens mentions, is it any real benefit? I would probably just add moving inside the jump state etc. Sometimes DRY can be in conflict with YAGNI or KISS, I wouldn't swear by any principle in particular. \$\endgroup\$
    – lozzajp
    Commented Jun 28, 2017 at 8:48
  • \$\begingroup\$ Thanks, guys. I'm going to look into the pushdown automaton to see if it fits the situation. Each character in my game has a set of states, most of which they share. The most simple would be Move, Jump, Fall, and Attack. For the player what triggers entering another state would usually just be a button press, but the AI is going to be a little more complex with an upper controlling layer with more general goals, for example Patrol and Chase. Each state has an animation and some behaviour. Is this not the ideal situation for a fsm? What else would you recommend? With fsm I can reuse states. \$\endgroup\$
    – Martin
    Commented Jun 28, 2017 at 11:38

2 Answers 2

1
\$\begingroup\$

There is a state machine called "Pushdown automaton". It is basically a Stack structure where you store your states. In your case, you could implement such a state machine, which isnt as hard. If your move state should be able to continue with jumping, you have to implement a dependency check(like in the code below).

This is an pseudocode example implementation in C# style(not tested):

Stack<State> states = new Stack<State>();

public bool ApplyState(State state){
    State latestState = states.Peek();
    // Immagine your latest state is STATE_MOVE
    // STATE_MOVE can continue with STATE_JUMP, so you can push STATE_JUMP to the stack
    // WARNING: "latestState" has to check if the parameter "state" alreay is its parent.
    // If you move and jump and move, you would have STATE_MOVE twice, because both can continue with each other. 
    if(latestState == null || latestState.CanContinueWith(state)) 
    {
        states.Push(state);
        return true;
    }
    return false;
}

// This function updates your state. 
// Keep in mind that you may have to change the update order
//  of the states because it is Last-in-First-out
public void UpdateStates(){
    foreach(State state in states){
        state.Update();
    }
}

This is how my implementation would look like.

Maybe this can give you an idea how to solve the problem.

\$\endgroup\$
0
\$\begingroup\$

A good solution example for such a situation is how animations are handled in different engines. Let's take for this example the unity engine and it's mecanim animation framework. The animations in there are also finite state machines. So if you need to play 2 animations at the same time, they introduce layers. So you have let's say a layer for the feet and one for the upper body. So if the character has to run and do shooting the feet layer will play the run animation and the upper body layer will play the animation for the shooting. So in your example I would break down the animations and states into different layers. So when you need to add up states, you simply have each layer played. So basically multiple finite state machines that run simoltanious.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .