Suppose you have a simple state machine for a game character with two states:
- StandingIdle
- Walking
In the update logic for the StandingIdle state you have (pseudo code):
if input received
setState(Walking)
In the Walking state you have:
intendedLocation = calculate new location based on current heading and speed
if intendedLocation is blocked
setState(StandingIdle)
else
move to intendedLocation
Now this creates the problem that the state machine can bounce back and forth between the states, which can result in an awful visual effect. This is because the StandingIdle state may switch to Walking, whereupon the Walking state may determine that something is blocking the way and subsequently switch back to StandingIdle. As long as there is input being received (ie. the player is trying to move), then the state machine will bounce back and forth between these two states.
In order to deal with this, the StandingIdle state could first check whether there is sufficient room in which to start walking. But that requires either duplicating logic that already exists in the Walking state, or exposing that logic in some fashion and calling it from the StandingIdle state. I am leaning towards the latter route at this stage.
Another option I considered was exposing some kind of canTransition()
method from my state objects and having the state machine call it prior to allowing a state change. That way, the Walking state could return false if there is insufficient room to walk. This, however, creates other problems.
Is there a best practice way to deal with this problem?