Advertisement

Fighters

Started by October 20, 2000 11:21 AM
14 comments, last by PsYcHoPrOg 24 years, 2 months ago
This question has been lying in my head for quite some time, however I've never found a good way to put it so that I can recieve the answer that I'm looking for. In fact, I still haven't found a good way to phrase it. But it's driving me nuts, so I'll give it a shot. In most fighters, (Street fighter series, mortal combat series, King of fighter series, ect.) a combination of keys/buttons can be used to execute certain special attacks or "moves". But how do you detect these combinations? Using DirectInput, I've really only understood how to get the input of one character/key at a time. The most common combination in fighters that I've seen is the "Down + Down-right + Right + Punch" combination. This is commonly referred to as the "fireball motion". How would I have the game think: "Hey, he's doing the 'fireball motion'. I'm going to have the player's character execute a (Your choice of destructive behavior here)". Do I create a history and read back every time a new key is hit to see if I can recognise a motion available for that character? That method seems a bit rediculous and slow. If anybody has any ideas, please post them up. "Remember, I'm the monkey, and you're the cheese grater. So no messing around." -Grand Theft Auto, London "It's not whether I win or lose, as long as I piss you off" -Morrigan, Super Puzzle Fighter II Turbo Edited by - PsYcHoPrOg on 10/20/00 11:24:17 AM
D:
The short verison is that I use a finite state tree to handle what commands need to be entered. Each state has a timeout which is the amount of time before the system goes back to neutral. I also use callbacks so that when you get to a certain state, a particular procedure can be called.

I am in the process right now of updating this systme to also set specific animations for the models.

Below is a link to my project''s messge board where I explain how I currently do what you are asking about.

[link]http://pub17.ezboard.com/fkinfirasoftswordplayengine.showMessage?topicID=7.topic[/link]


Regards,

Kinfira
Lead Programmer
KinfiraSoft
[link]http://kinfirasoft.8m.com[/link]
Regards, KinfiraLead ProgrammerKinfiraSoftMakers of Swordplay, a 3D fighting game engine.Check out our home on the web:http://www.kinfirasoft.com
Advertisement
I just happened to start reading the DirectInput docs yesterday. Here''s a passage:

"When DirectInput input data is buffered (see Buffered and Immediate Data), each DIDEVICEOBJECTDATA structure contains not only information about the type of event and the device object associated with it, but also a time stamp and a sequence number."

That should help with tracking keypress sequences and such. If you use event notification it''s a moot point (everything will automatically happen in sequence), but the docs say certain joysticks will not trigger events that way, they''ll only support buffered input. If you''re reading input each frame with DI all the input events in the buffer will have time stamps and sequence numbers so you can trigger the events in the correct sequence and still use a method like Kinfira''s state tree (sounds like a good way to handle it).
Thanks. I''ll give these methods a shot.

"Remember, I'm the monkey, and you're the cheese grater. So no messing around."
-Grand Theft Auto, London

"It's not whether I win or lose, as long as I piss you off"
-Morrigan, Super Puzzle Fighter II Turbo
D:
Before DInput, what I used to do was create my own buffer, and every time a button was pushed I''d stick it in the buffer, and remove the last button pressed from the buffer. Then I''d check the buffer for various combinations of keys, so if the keys DOWN, then FORWARD, then ACTION were pressed that would be the basic motion for a fireball so I''d start the fireball animation sequence. Also, I''d remove the last character in the buffer every half second or so automatically so you couldnt start a fireball motion or something and finish it five minutes later.

------------
- outRider -
The idea about a finite state machine is a good one. I was thinking more of a stack that acts as an input buffer. Each new key press is pushed onto a stack and the stack is checked each cycle for ''move'' matches. If anywhere in the stack there is d,df,f,P then execute a fireball. Again, I think the state machine is better but it requires more planning.
Advertisement
Another way of doing this, I thought of while reading the posts, is to only make checks when "action keys" are pressed:

    switch (key)  case ''ACTION_PUNCH'':  {    if ((KeyStack[iThisKey] == ACTION_DOWNRIGHT) &&       (KeyStack[iThisKey-i] == ACTION_DOWN)     Fireball();  } break;    


Sorta similar, but only making checks when "end" keys are pressed.


MatrixCubed
With the stack idea, if you just pushed all input on the stack, how would you go about checking to make sure the move can actually happen?

For example what if you were in the middle of a jump? If you pushed all commands on the stack, how would you know not to execute the fireball (unless you can do them in the air)? Or if it was buffered, it seems like it would execute the fireball directly after you finished the jump (which may be undesireable) in which case the joystick may be back in a neutral state.

Could you explaing how the command stack works a bit more?


L8tr, Kinfira.
Regards, KinfiraLead ProgrammerKinfiraSoftMakers of Swordplay, a 3D fighting game engine.Check out our home on the web:http://www.kinfirasoft.com
Uh

Use DX immediate (not buffered).

Every time you check the state of the keyboard it returns an array of DIKEY states which will note all buttons triggered.

I wouldn''t use buffered modes for input.
quote: Original posts by Kinfira

The short verison is that I use a finite state tree to handle what commands need to be entered. Each state has a timeout which is the amount of time before the system goes back to neutral. I also use callbacks so that when you get to a certain state, a particular procedure can be called.


I''ve checked out everything you''ve posted here, but I''m still a bit confused. Are you using the trees along with an input buffer (described below)? I don''t see how you''re keeping track of what the user has pressed - what if he/she has pressed something not in the tree?

BTW: Are you still working on the Swordplay Engine?

quote: With the stack idea, if you just pushed all input on the stack, how would you go about checking to make sure the move can actually happen?


The way I see it (and the way I''m currently trying to implement), you would have a linear buffer containing the information of the last couple of seconds or so of user input. If you''ve played Killer Instinct Gold for N64 and have done any training mode in it, you''ll have noticed that along the bottom of the screen, it shows what you''ve entered from the keypad. Along the bottom of the screen, you would see all sorts of arrows pointing in the directions you had been pressing it, and the attack buttons you had been pressing - all in the order in which you pressed them. It doesn''t show any held-in buttons or timing between entries - but it''s assumed that they would be very valid information for the buffer. You would simply look through the buffer every frame to see if something valid was done, and then you perform the move.

quote: For example what if you were in the middle of a jump? If you pushed all commands on the stack, how would you know not to execute the fireball (unless you can do them in the air)? Or if it was buffered, it seems like it would execute the fireball directly after you finished the jump (which may be undesireable) in which case the joystick may be back in a neutral state.


Well, the state trees - as you had said in the information given thru the links - would have function pointers on the leaves, and these funcitons would check the state of the fighter before attempting to execute. For example:

if (fighter.onground && fighter.freeToAttack)   fighter.ThrowGroundFireball();if (fighter.airborne && fighter.freeToAttack)   fighter.ThrowAirFireball(); 


Unless you want to make the tree even bigger and more unwieldy, you could have fighter state node switching right at the root of the tree - but I''d rather keep the tree simple. However, just as you would have these functions here using the state tree method, so would you have them in the buffer only checks - exactly the same way. You need to extract the moves in either method, and you do your checks on them in basically the same way as far as I''m concerned.

I can see a really great way to improve on the input buffer checking using your proposed state tree method - keep all of the moves in the tree and use it to check with - I plan on using it now; it seems to keep everything much cleaner as I think about it. Unfortunately, I can''t see any use for your state tree proposal on its own. Maybe I''m missing something though. Perhaps if you explain how the input that was retrieved from the input devices is stored for use with your method, and how you extract the information out of where you store it, I might be able to understand a little more.

Sorry about the ungodly size of the post.. hehe
SteelGolem

This topic is closed to new replies.

Advertisement