How to handle complex inputs in 2D platform game?

I am trying to add keyboard control for my character in 2D platform game with JavaScript. The character can walk, dash and jump. Here is my current code:

if(keyboard['LEFT']) {
//walk to left
//...
} else if (keyboard['RIGHT']) {
//walk to right
if(keyboard['SHIFT'] && !jump) {
//dash
}
if(keyboard['JUMP']) {
}
if(keyboard['SHIFT'] && keyboard['JUMP']) {
//dash and jump (move further and faster)
}
if(keyboard['JUMP'] && keyboard['SHIFT']) {
//hold the right key, pressed jump key, and then pressed shift key
//it expected to jump to right here, because character can not dash
//in midair, but it will conflict the if condition above.
}
} else if (keyboard['JUMP'] && onGround) {
//jump
} else if (keyboard['SHIFT']) {
//dash
if(keyboard['JUMP']) {
//dash and jump
}
}


I am confused that there are many if() else() statement in my code, and it seems that I need to control the order of keyboard inputs.Is there an easy way to handle that?Am I going the right way? If not, what is the common way to achieve that? Please, Any help would be appreciated.

This is an excellent question because you are experiencing a problem that's quite commonplace with less experienced programmers: attempting to solve your problem with a purely imperative approach. Luckily this problem has been encountered and solved by people much smarter than I, thanks to the mathematical concept of a finite state machine.

A finite state machine is just a fancy mathematical term of a type of system that can be in any of a finite number of states at any one time. A finite state machine is just a bunch of states and transitions, and in diagram form it looks a bit like this:

I'm not going to go into great depth because I know of someone who has already written an extensive explanation (with examples and diagrams) about this exact problem. Thus, I am going to refer you to Robert Nystrom's excellent book Game Programming Patterns, in which he discusses the finite state machine pattern in great detail, solving this exact problem.

• P.S. Yes, the image is also from his book.
• P.P.S No, I have no affilation to him, I just love his book - it's a damn fine book.
• Another concept that's useful in conjunction with this is combining multiple key presses into an input axis / vector or direction code. That way you can have a state for horizontal movement that just reads the horizontal movement axis (+1 for right vs -1 for left) without needing to handle the left vs right cases separately, and without scattering keyboard-reading code throughout your state machine. Apr 23, 2017 at 17:21
• Wow,thank you for this detailed answer! Solved my problem! I found an article FSM Implementation with AS3. you lead the right way! Apr 23, 2017 at 17:26
• @DMGregory I think you should put that up as another answer. It's not exactly a full solution, but I'd argue it definitely helps to "control the order of keyboard inputs", and it's technically separate to my state machine suggestion (i.e. it can be used without a state machine) so it makes more sense as its own thing. Apr 23, 2017 at 17:30
• It's already an answer on a different question, so I just wanted to provide a signpost to it here rather than duplicate the content. ;) Apr 23, 2017 at 17:42
• @undefined000 Most of the credit should go to Nystrom since he's the one who wrote the article, I'm just passing the knowledge on. I've read that exact article before, it's also quite good but I'd recommend making states objects rather than functions because they're more flexible (state objects can have multiple functions for conditions like 'ExitingState()' and 'EnteringState()' which allow you to set up and destroy the state). Also, stack based FSMs are good but they can get you into trouble, as explained in this answer. Apr 23, 2017 at 17:43