Skip to main content
GameDev.net gamedev.net
🔒 Locked

Input Sequences for Fighting Game Combos

Started by CDProp Sep 8, 2010 at 12:36 AM 1 replies 9.5k views
Original Post
CDProp
CDProp
Hello sir or madam or sirs or madams,

So, I am working on a game that has some special moves that are invoked through button sequences, much like a fighting game. So far, I've just got this ButtonSequence class that holds a list of the buttons that the player pressed, in the order that they pressed them.

Every time the player presses a button on the controller, that button press is added to the list. Then, the last N button presses in the list are checked against each special move combo for any matches.

If there is a match, then the special move is executed and a new, empty ButtonSequence object is created.

Additionally, if there is more than 250ms between button presses, the ButtonSequence is broken and a new, empty ButtonSequence is created.

And this is all well and good for special move combos involving a simple series of button presses, but as I think about the fighting games that I have played in the past, it is never this simple. There are other considerations:

1. Some special moves involve holding a button down. While the button is being held, the player often (but not always) has to press other buttons in a certain order. The timing is varied. Sometimes, the initial press of the 'held' button(s) is part of the sequence, and must be quickly followed by the rest of the sequence or else the sequence is broken. Sometimes, it doesn't matter -- as long as you were holding the button while performing the rest of the sequence, it works, even if you started holding the button several minutes ago. Sometimes, the button must be held for a specific amount of time, e.g. Liu Kang's bicycle kick. Sometimes this time must be precise, and sometimes it can be held as long as you want as long as it exceeds some minimum.

2. Many buttons sequences seem to have buttons that can be ignored. For instance, with Liu Kang's bicycle kick, it doesn't matter if you press other buttons while holding down LowKick. In fact, you can even execute other special moves while holding down LowKick. As long as you hold LowKick for 5 seconds before releasing it, you're golden. But with other moves, it very much matters. Pressing a button that isn't in the sequence will break the sequence.

So it gets very complicated. I have a lot of ideas about how to approach this, but I'm sort of overwhelmed by the hairyness of it all. I am hoping that, since this topic is almost as old as the video game medium itself, there will already be some solid algorithms in place. Something like, perhaps, what DFA's are to regular expressions (I actually explored this route for button presses a bit, but it wasn't obvious to me how to get it to work, with all of the button holds and timing issues).
Brain
Brain
In my opinion what you should do is decide how it will work in your game and be consistent. Do you want to allow special moves where a button must be held while other buttons/directions are being issued, or just one button at a time?

If you want to allow for buttons to be held down while other actions are going on, maybe you should have bitmasks in your pattern. For example, the top four bits indicating buttons being held down and the bottom four bits in a byte indicating buttons that are simply pressed WHILE other buttons may be held down as part of the sequence. Would this do what you need?

So, if you had four attack buttons A,B,C,D (lets keep this example simple and for now omit directional buttons, the concept is the same) and your move involved holding down A whilst pressing B, C and then D, you could map the bits as follows:

Button ABCDABCDBit    76543210


Then, your sequence, in binary, would be:

10000100 = 0x8410000010 = 0x8210000001 = 0x81


Such a system would allow for pretty complex combinations of button presses, releases, and buttons to be held down whilst executing other button presses.

Let me know what you think :-)
Vass
Vass
I would suggest taking a look at how MUGEN handles its input. They have a very advanced engine and allow scripting for moves.
I'm fairly confident that it will tickle down into using a graph or a tree which gets propagated according to key presses.

Here is my invention for this problem:

The nodes in the tree have timing constraints and button state constraints.

for example:
enum ButtonState{ Up, Down, DownAnyTime, UpAnyTime, DownCharge, UpCharge};

The input you are going to take needs to be buffered in two different ways:
State
Sequence

The state input buffer knows about all the buttons you have in your game and knows when about the latest press and release.

The sequence input buffer is a queue that knows about the order buttons were pressed in.

On every button event (press or release) you need to walk the tree from the root. For simplicity your tree should be the inverse of the input you expect, example:
F,F,HK (forward, forward, high kick), tree would be HK,F,F.
This means you start matching your sequence buffer from the end and traverse your tree from the root.

When traversing the tree you match if the given input event allows a transition into any of the child nodes. If it does you step into that child node, if it doesn't you move to the next input in the sequence buffer.

Now for the interesting Bycicle kick parts, this is where your button states come in handy. Since the button state may be UpCharge, when you traverse the tree and check for possible childeren, if you come across a LK button event with the state changed to up and there is a node with LK DownCharge (in your case this would hang directly from the root) you check the State buffer to see how long that button has been held down.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.