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.

Coding > [SOLVED] coding the "shoryuken"

#74001 - deltree - Wed Mar 01, 2006 4:36 pm

Hi,
I've been wondering how it would be possible to code a "special move" handler.
I mean, generaly, when the player press A or B, or a control key, the character moves or do its actions.

How Could I program a special move, I mean, the character will do his move only if the keys like "UP then DOWN, then A then B" are pressed sequentially, in that specific order?
what would be the good way to program this?

maybe you remember in street fighter 2, if you wanted to trigger the dragon punch (shoryuken), you had to do this move:
"RIGHT then DOWN, then RIGHT/DOWN then RIGHT then buttonA"
this sequence needs to be played in a short time (less than 1 second for the whole thing.) else, the dragon punch is not triggered.

I tought of doing an array that would keep every moves, then I will check the whole array to see if the "special move" sequence is somewhere inside it, but it would take a long time to compute...


Last edited by deltree on Thu Mar 02, 2006 8:14 pm; edited 4 times in total

#74011 - Palamon - Wed Mar 01, 2006 6:52 pm

You could always incorperate the special moves into the area where you deal with normal moves and just have it check the requirements of the special moves and see if they have been met.

Here's my idea:

you can have a variable flag for each special move, an array with the required moves, and when the variable flag gets to the end of the array, preform the special move

this is just some pseudocode

Code:



const int dragonpunch[5] = //required movement array to preform a dragon punch
{
key variable for just Right pressed,
key variable for just Down pressed,
key variable for just Right+Down pressed,
key variable for just Right pressed,
key variable for just A pressed};


struct specialmoveflag
{
     int currentmovement;
     int movetimer;
}


specialmoveflag   dragonpunch;


dragonpunch.currentmovement = 0;


//now in your player input section, put something like this right before you handle normal controls (left, right, punch, kick)

if(keyspressed == dragonpunch[dragonpunch.currentmovement+1])
{//if you pressed the next button, move ahead on the array
dragonpunch.currentmovement++;
dragonpunch.timer = 10; //max number of game cycles to allow the user to press the next button in the sequence

     if(dragonpunch.currentmovement = 5)
     //then do the move and reset dragonpunch variable

}


//now if they didn't move onto the next move on the series, see if they can continue to try to do the move


if(dragonpunch.currentmovement != 0)
{
dragonpunch.timer--; //reduce the number of game cycles they have to press the next move

if((keyspressed != dragonpunch[dragonpunch.currentmovement]) || dragonpunch.timer ==0))
//if out of time or press the wrong move, start from beginning
dragonpunch.currentmovement = 0;
}




So, in other words

if they press the correct button, they advance on to the next move in the array.

If they continue to press the current button, a timer counts down and then sends you to the end of the line in the seq.

If they press something other then the most recent correct button or the next correct button, it sends you to the end of the line in the seq.

#74048 - keldon - Thu Mar 02, 2006 12:04 am

Check out finite state machines in the FAQ

#74054 - sajiimori - Thu Mar 02, 2006 12:59 am

I'd do it Palamon's way. I posted some fairly complete code for it a while back, but you'd have to search for it.

#74123 - deltree - Thu Mar 02, 2006 4:49 pm

Code:
#include <mygba.h>
// Global Variables
const int dragonpunch[5] = {BIT3,BIT1,BIT3+BIT1,BIT3,BIT4};//required movement array to perform a dragon punch

int score=0,key=0,currentmove=0,timer=0;

void vbl_func()
{
   key=0;
   //check the pad move
   if(F_CTRLINPUT_RIGHT_PRESSED) key=BIT3;
   if(F_CTRLINPUT_DOWN_PRESSED) key+=BIT1;
   if(F_CTRLINPUT_LEFT_PRESSED) key+=BIT2;
   if(F_CTRLINPUT_UP_PRESSED) key+=BIT0;
   if(F_CTRLINPUT_A_PRESSED) key+=BIT4;
   if(key==dragonpunch[currentmove] && currentmove<5)
   {//if you pressed the next button, move ahead on the array
      currentmove++;
      timer = 20; //max number of game cycles to allow the user to press the next button in the sequence
   }
   if (timer==0) currentmove=0; //Reset dragon punch if player takes too long to perform the dragon punch
   if (currentmove!=0) timer--;
   if(currentmove == 5) {currentmove=0;ham_DrawText(1,1,"DRAGON PUNCH:%d   ",++score);}
     ham_CopyObjToOAM();
} // End of vblFunc()

int main()
{
   ham_Init(); //init..
    ham_InitText(2);//initialize text functions
   ham_SetBgMode(1); // Setup the background mode
    ham_StartIntHandler(INT_TYPE_VBL,(void*)&vbl_func);//handle the vblank..
    while(1) {} //infinite loop
} // End of main()


here's a working code for this , and here is the resulting ROM for the dragon punch, here >>>HERE
If any of you knows how to do the dragon punch in SF2, can he tell me if it as the good feeling ? too speed, too slow, or just the right triggering ?

#74136 - Palamon - Thu Mar 02, 2006 7:07 pm

I think it works fine and the timing seems to be good, you don't have to be perfect to get the move, but you do need to know the move sequence comfortably.

Although there is one thing fishy.

In your code, you allow someone to press the wrong button and still continue with the sequence.

so if you are quick, you register a dragon punch by pressing
right, B, down, B, down+right, B, right, B,A

or some other incorrect move into the sequence and still get a correct dragon punch.

That's why in my code, if the keys pressed wasn't the current move or blank, then it reset the sequence.

#74142 - keldon - Thu Mar 02, 2006 8:03 pm

Street fighter, and most beat em ups allow you to enter a few incorrect buttons when pulling off moves. It's what introduced the 'double/tripple wammy' combos in street fighter II. It was in fact a bug, but went unfixed when [I believe] testers spoke of the amazing combo feature. Capcom spoke of this in one of the game development mags.

For fun when using ryu/ken; approach a guy and do a dragon punch. But when you are in the diagonal position press punch, and then continue with the dragon punch. That will pull off a double dragon punch; if my memory serves me right - may require medium punch. I'd tell you how to do the tripple dragon punch; but I'd have to dig up that street fighter disc and hope it works.

#74143 - deltree - Thu Mar 02, 2006 8:06 pm

Actually, I tought about this problem, but it seems to be working like this in the real game.
The dragon punch can be triggered even if some "parasite" keys are pushed within the correct sequence.
so, that's correct to me...