gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

C/C++ > Button Combos

#47507 - QuantumDoja - Sat Jul 09, 2005 10:04 pm

Hi, I have a button sequence that i want to detect for a special move, much like street fighter or tekken.

Example: Up, Down, Left, A + B
Example: Up + R, Down + L, A, B

I have this post: http://forum.gbadev.org/viewtopic.php?t=4128&highlight=button+combo

is this the right lines to code, having 1 function per combo?

I want something like [pseudo] - but if i have 32 special combos, it will have to check each one - maybe slow.
Code:

//Up + R, Down + L, A, B
if (button_Up pressed && button_R pressed) {
 then if (button_down pressed && button_L pressed) {
  then if (button_a pressed) {
   then if (button_b pressed) {
     do combo xyz
    }
  }
 }
}

_________________
Chris Davis

#47508 - tepples - Sat Jul 09, 2005 10:12 pm

Not if you don't want the "if then" to freeze up the rest of the game. Look up "finite state machine" on a search engine.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#47526 - Mucca - Sun Jul 10, 2005 3:07 pm

Buffer the input once per frame, and make it available throughout the system. For such combinations, it will be important to store whether buttons have just been pressed down, are still pressed, have just been released, as well as timings for button presses. A certain tolerance is also vital (either frame or time based). Eg if the combo is A + B + Down, its rather unreasonable to expect the player to have such timing that they can press all three in precisely the same frame, but by the same token it would make no sense at all if the player could press and hold each button individually at, say, one second intervals, so store some timings for each button, then you can adjust the tolerance times until they "feel right".

edit: oops, just read the previous thread, which makes my post pretty redundant, sorry

#47536 - Touchstone - Sun Jul 10, 2005 5:38 pm

I think a good idea would be to have an array of buttons that needs to be pressed, and each frame you check if the current keys match the current position in the array and if so, move on to the next index in the array, or if this was the last index, perform the move.

Like so:
Code:
KEY_UP = 1
KEY_DOWN = 2
KEY_A = 4
KEY_B = 8
Key moveSuperDuperAttackKey[3] = {KEY_UP, KEY_DOWN, KEY_A+KEY_B}

void oncePerFrame()
{
    Key currentPressedKey = sysGetKey();
    if (moveSuperDuperAttackKey[ moveSuperDuperAttackKeyIndex ] == currentPressedKey)
    {
        if ( moveSuperDuperAttackIndex == moveSuperDuperAttackKeyLength )
            performSuperDuperAttack();
        else
            moveSuperDuperAttackKeyIndex++;
    }
}


Ofcourse variables and functions can be structured different to avoid odd names. And as someone mentioned, the game should have some sort of mechanism to reset the array index if the move is performed incorrectly. What constitutes as incorrectly is of course up to the game design.
_________________
You can't beat our meat

#47561 - Miked0801 - Sun Jul 10, 2005 10:44 pm

Also, no input that takes over N tics should reset any combos - while input every few tics should be counted as in sequence. Don't make the player input at 60Hz, but don't let him input a command every 1 second either :)