A programming question

iKotomi

[10] Knight
So I've been working on programming a game engine off and on, and am currently working on input detection. For reference, I'm using C++ and SDL for inputs, graphics, miscellaneous stuff I can't be bothered to learn winapi for. The problem I have is as follows.

The way the computer polls the keyboard, you can only receive one input at a time (press or release). You can sort of get around this by holding internal variables so that, for example, if left is pressed, if the internal variable for down is true, you register a downback motion.

This is all fine in games like shmups, but in fighters there's a big difference between pressing up and right in sequence and up and right simultaneously. A similar problem exists with multiple button commands like A+B+C. To address this, my guess is that you need to read inputs continuously for a very small fraction of a second, and then interpret that, so if say, down and down right are pressed within a millisecond of each other, than that should just be read as downforward.

Does anyone know how small this window should be so that you could read all the inputs without it mushing separate inputs, and avoid problems with the granularity of the cpu clock? Or is there a better way to do this completely?
 
I have no clue what the specific delay time is. If i was you i'd guess starting at an 8th of a second. I dont think you should have a problem bogging down the PC. Every robot I've ever built relied heavily on using lots of different delays and polling several inputs and it was never enough to bog up a 1Khz MCU, so a 1GHz+ computer should be fine.....I could be wrong though.

As far as i know, the way you explained is the only way to do it.

sorry this post isn't very helpful, I just thought i'd throw in my 2 cents. I wish ya luck on completing this game. Everything i've ever started ends miserably.
 
This is a tricky problem.

You want to keep track each frame of what keys are held down, and keep track of the total time that the key has been held down for. So you can differentiate someone tapping A and holding then releasing A. What that threshold between a tap and a release is, is something you'll have to experiment with until it feels right for your game.

What you really care about are when the key releases happen, since that indicates the end of an input.

If doing a Soul-Calibur style game, I would keep a queue data structure of the inputs going on. Adding new inputs to the end of the queue. Then each frame, I would start at the front of the queue and remove any inputs that are too old to be useful anymore. Then I would compare that input queue to the character's moveset. So, if the queue looked like: 44236B, I would see if 44236B is a valid input for that character, then 4236B, then 236B, then 36B, 6B and finally B. The first one of these that is valid would be the move that I would do. Inputs would only go into the queue when the key is actually released and how long those keys were pressed, so, you can tell the difference between say a A+B input and a [A+B] input, because the queue would say that the user held A+B down for say 3 or more frames to trigger a [A+B] instead.

If neutral is an important input, then you need to add it to the queue when no other direction is pressed, so you can handle moves like 23658B.

You might also want to look at the state of the directional inputs when processing an input. So if I hold down B, and then press 3 as I release B, that it processes 3 instead of a straight . That's again up to experimentation as to what feels right.

A move like AA could be handled by putting the character into "mini stances". So, if you hit A, you execute A going into the "A stance". This stance then has say 2 possible moves, a A followup for a AA or a K followup for an AK. The "AA mini stance" could have a B followup to handle the AAB move. With this approach, you don't care about anything about the directional inputs leading up to a single button press and that one button (where a "button" is A, B, A+B, B+K, A+B+K or whatever). Stances fall naturally out of this, since, you can have the stances either time out (making AA only work if you input the 2nd A fast enough) or they can leave you in them indefinitely (like say Ivy's sword state stance).

Now if you want to be lenient (like SC is) you start having to try filtering these inputs, so you might allow a 2[3]6B input to be a 236B depending on how long of a time period there was that 3 was held down (though I suppose if it was held down too long, the input queue would look like 36B).

An interesting question, is what does SC do when you say hold down A for a second and then release A at the same time that you tap B, does it interpret that as A+B or [A+B]?

This is all a tad jumbled, but, something along this line should work. Lots of ways of doing it.

Now, you run into problems with this approach if the framerate drops too low. Since you can end up with a potentially enormous number of inputs queued up, or missing inputs altogether depending on how SDL is giving you data (I've never used SDL myself). You can get around this some by spinning off a seperate thread dedicated to processing keyboard input that the main game thread then reads every frame, so if rendering a frame takes 50ms, you aren't ignoring keyboard input for those same 50ms.

I don't know how SDL handles things, but, in raw win32, these keyboard messages queue up and you can then process them whenever you want. You might have to just ignore any inputs that are too old. Which sucks, but, the game isn't exactly running optimally anymore at this point.
 
Back