[SOLVED] Charging anim for punch and kick

kimono

Well-known member
Hi everybody :)

I've got two basic attacks, punch (A) and kick (A2). I wish to make a charging animation with keep pressing A or A2 (different from A charging).

Here's what I try to set:
Code:
anim	attack1 #Punch
	delay	8
	offset	42 110
	bbox 30 6 27 104
	cancel 1 6 0 A freespecial21
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A2" 0
	sound	data/sounds/punch.wav
	frame	data/chars/karatedo/punch1.gif
	frame	data/chars/karatedo/punch2.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/punch2.gif
	frame	data/chars/karatedo/punch1.gif

anim freespecial21 #Charge
	offset	44 102
	bbox 26 2 32 100
	delay	3
	sound	data/sounds/yossha.wav
	frame	data/chars/karatedo/chargingpunch1.gif
	frame	data/chars/karatedo/chargingpunch2.gif
	frame	data/chars/karatedo/chargingpunch3.gif
	
anim chargeattack
	offset	44 104
	bbox 26 4 32 100
	chargetime	0.4
	delay 13
	frame	data/chars/karatedo/chargepunch1.gif
	attack5 42 0 45 42 10 1 1 0 0 0
	frame	data/chars/karatedo/chargepunch2.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	attack5 81 12 40 42 10 1 1 0 0 0
	sound	data/sounds/yossha.wav
	@cmd	dasher 1 0 0 1
	frame	data/chars/karatedo/chargepunch3.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	attack5 80 26 30 38 10 1 0 0 0 0
	frame	data/chars/karatedo/chargepunch4.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	@cmd	stop
	frame	data/chars/karatedo/chargepunch5.gif

Chargeattack works well but not my charging anim. Any clue to resolve that? Maybye an anim charging function would be nice to add to a further Openbor engine update, won't it?
Thank you for taking time to read this small problem :).
 
charging as in charging bull or charging as in standing still & making a glowy fist that you will unleash?

nighslashers has the second type, but with no frames , only one static frame that shakes - it works by pressing block plus direction
 
oldyz: I just wish to have this kind of animation when kick or punch button is keeping pressed:
b9Mdc1W.gif
 
So I think I need help with this as well,

Basically in double dragon, I've created 3 set of sprites for billy to hold down the punch button for atleast 3 seconds and if the player let's go of the punch button after the 3 seconds than billy throws a (charged)  punch.

Natively openbor has a 3 seconds hold attack, but how can I set it up to play the beginning of the charge animation,  then the charge animation and loop that unti I let go of the punch button to than play the final part of that animation,  which is the final punch part?


 
nsw25 said:
check my DBZ tournament mode to see how its done if you need the answer urgent, available thatcherproductions.org (about to head out sorry but when im back at a computer ill try to paste the stuff here for you)

Sounds cool and thanks, and I will also check out the game as soon as I get a chance.
 
Thank you again, I will test this later without the mp charge.

So is this @cmd  keyint "ANI_FOLLOW2" 0 "A3" 1
Script available on all openbor games?

Or do I need to implement it in the scripts folder?

EDIT after downloading the DBZ game and inspecting it - I notice that "Free special 3" is performed via COM A3

But I guess I didn't explain myself well enough - since what I'm trying to do is hold down A1 to trigger my own freespecial ( which is freespecial 81)

so , that's what I'm having trouble with - simply knowing how can I trigger my freespecial81 by simply pressing down A1 for say 3 or 4 seconds - letting go of the A1 button and triggering Freespecial 81.

Than animfollowing it with say animfollow2 to loop the animation that charges the attack and finally letting of A1 to animfollow 2 which is the actual attack.



EDIT 3 : So basically  i need to add the animscript.c  to the scripts folder and
this is all I need correct?

Code:
void keyint(void Ani, int Frame, void Key, int Hflag)
{// Change current animation if proper key is pressed or released
    void self = getlocalvar("self");
    int Dir = getentityproperty(self, "direction");   
    int iPIndex = getentityproperty(self,"playerindex"); //Get player index
    void iRKey;

      if (Key=="U"){ //Up Required?
        iRKey = playerkeys(iPIndex, 0, "moveup"); // "Up"
	} else if (Key=="D"){ //Down Required?
        iRKey = playerkeys(iPIndex, 0, "movedown"); // "Down"
	} else if (Key=="L"){ //Left Required?
        iRKey = playerkeys(iPIndex, 0, "moveleft"); // "Left"
	} else if (Key=="R"){ //Right Required?
        iRKey = playerkeys(iPIndex, 0, "moveright"); // "Right"
	} else if (Key=="F"){ //Forward Required?
          if (Dir == 0){ // Facing Left?
            iRKey = playerkeys(iPIndex, 0, "moveleft"); // "Left"
          } else { // Facing Right
            iRKey = playerkeys(iPIndex, 0, "moveright"); // "Right"
          }
        } else if (Key=="B"){ //Back Required?
          if (Dir == 1){ // Facing Right?
            iRKey = playerkeys(iPIndex, 0, "moveleft"); // "Left"
          } else { // Facing Left
            iRKey = playerkeys(iPIndex, 0, "moveright"); // "Right"
          }
        } else if (Key=="J"){ //Jump Required?
        iRKey = playerkeys(iPIndex, 0, "jump"); // "Jump"
	} else if (Key=="A"){ //Attack Required?
        iRKey = playerkeys(iPIndex, 0, "attack"); // "Attack"
	} else if (Key=="A2"){ //Attack2 Required?
        iRKey = playerkeys(iPIndex, 0, "attack2"); // "Attack2"
	} else if (Key=="S"){ //Special Required?
        iRKey = playerkeys(iPIndex, 0, "special"); // "Special"
	} else if (Key=="A3"){ //Attack4 Required?
        iRKey = playerkeys(iPIndex, 0, "attack3"); // "Attack3"
	} else if (Key=="A4"){
	iRKey = playerkeys(iPIndex, 0, "attack4"); // "Attack4"
	}

      if (Hflag==1){ //Not holding the button case?
        iRKey = !iRKey; //Take the opposite condition
	}

      if (iRKey){
//        performattack(self, openborconstant(Ani));
//        updateframe(self, Frame);
        changeentityproperty(self, "animation", openborconstant(Ani),2);
        changeentityproperty(self, "animpos", Frame);
      }
}



And this is the current code that I'm working with for billy

Code:
#-------------------------------------------------------------------------






#Mega Punch

anim freespecial68 # mega punch 
	loop	0
	delay	8
	offset	77 170
      bbox	60 55 40 100
      frame	data/chars/billy/hp1.png
      frame	data/chars/billy/hp2.png
      frame	data/chars/billy/hp3.png
      sound  data/sounds/slide.wav
      frame	data/chars/billy/hp4.png
      @cmd   keyint "ANI_FOLLOW82" 0 "A1" 0


anim follow82 # mega punch part 2
      loop 1
      delay 6
      offset 77 170
     bbox	60 55 40 100
     @cmd   keyint "ANI_FOLLOW83" 0 "A1" 1
     frame	data/chars/billy/hp5.png
     @cmd   keyint "ANI_FOLLOW83" 0 "A1" 1
     frame	data/chars/billy/hp6.png
     @cmd   keyint "ANI_FOLLOW83" 0 "A1" 1
     frame	data/chars/billy/hp4.png
     @cmd   keyint "ANI_FOLLOW83" 0 "A1" 1
     

anim follow83 # mega punch part 3
      loop 0
      delay 6
      offset 77 170
     bbox	60 55 40 100
     attackone 1
     hitfx   data/sounds/maxhit.wav
     frame	data/chars/billy/hp7.png
     frame	data/chars/billy/hp8.png
     frame	data/chars/billy/hp9.png
     attack  90 68 60 34 40 1
     dropv 7.5 1.5
     frame	data/chars/billy/hp10.png
     attack  0 0 0 0 0 0
     frame	data/chars/billy/hp11.png
     frame	data/chars/billy/hp12.png
     frame	data/chars/billy/hp13.png





#-------------------------------------------------------------------------


 
kimono said:
oldyz: I just wish to have this kind of animation when kick or punch button is keeping pressed:
b9Mdc1W.gif
Hi kimono
Do you want a "charge mp" animation like KOF, or you want a "charged attack" like SOR?

For "charge MP"
If you want to repeat an animation while holding a button, I will suggest using the same "block" animation from SOR2X. Then, it is possible to add any effect you want, like charge mp for example.

Code:
void keyLoop(void key, int frame)
{//Loops defined frame if defined key is held
	void self 	= getlocalvar("self");
	int iPIndex = getentityproperty(self,"playerindex");

	if(playerkeys(iPIndex, 0, key)){updateframe(self, frame);}
}

Code:
anim freespecial2 #BLOCK
	loop	0
	delay	12
	offset	62 126
	bbox 	50 61 22 68
	@cmd block 1
	frame	data/chars/heroes/axel/block00.gif
	@cmd keyLoop "attack3" 0
	@cmd block 0
	frame	data/chars/heroes/axel/block00.gif

In the example above, when the animation advances to the frame "1", if you are holding the "attack3" button the animation will always go back to the frame "0" . So, I added another code to change the "blocking" status, but you can replace it by any other script you want.
If no buttons are held, the "@cmd keyLoop" will be ignored and the "@cmd block" can disable the "blocking" status.
 
Kratus: Thanks, that's very kind to you to help me :). I will use no mp for this move:
5G5YW4i.png

The lone problem is that these two buttons are used already for basic punch and kick, unlike your block anim that is used in SOR in another button.
Maybye it can work like this?

Code:
anim	attack1 #Punch
	delay	8
	offset	42 110
	bbox 30 6 27 104
	@cmd keyLoop "attack1" 0
	frame	data/chars/karatedo/chargingpunch1.gif
	frame	data/chars/karatedo/chargingpunch2.gif
	frame	data/chars/karatedo/chargingpunch3.gif
	cancel 1 6 0 A freespecial21
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A2" 0
 	sound	data/sounds/punch.wav
	frame	data/chars/karatedo/punch1.gif
	frame	data/chars/karatedo/punch2.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/punch2.gif
	frame	data/chars/karatedo/punch1.gif

Code:
anim	freespecial #Kick
	delay	8
	offset	61 110
	bbox 48 8 26 102
	@cmd keyLoop "attack2" 0
	frame	data/chars/karatedo/chargingkick1.gif
	frame	data/chars/karatedo/chargingkick2.gif
	frame	data/chars/karatedo/chargingkick3.gif
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A" 0
	sound	data/sounds/kick.wav
	frame	data/chars/karatedo/kick1.gif
	frame	data/chars/karatedo/kick2.gif
	attack1 68 33 70 20 10 0 0 0 0 0
	frame	data/chars/karatedo/kick3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/kick2.gif
	frame	data/chars/karatedo/kick1.gif

I'm afraid of that way we can no longer execute basic punch and kick.
 
kimono
In this case I suggest another solution. I developed a simple charge attack for this purpose, it will combine the keyLoop and keyAni in one script. Here's an example:

This is how the animation will be
Code:
anim attack1
	fastattack 1
	jugglecost 5
	forcedirection -1
	loop	0
	delay	4
	offset	62 126
	bbox 	50 55 23 74
	hitfx	data/sounds/LowPunch.wav
	sound	data/sounds/LowAttack.wav
	frame	data/chars/heroes/axel/a100.gif
	attack 62 61 42 13 2 0 0 0 5 12
	frame	data/chars/heroes/axel/a101.gif
	@cmd keyCharge "ANI_ATTACKBOTH" "attack" 1 100
	attack 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/heroes/axel/a100.gif

And this is how the script keyCharge works
Code:
void keyCharge(void ani, void key, int frame, float limit)
{//Perform a custom charge attack when a defined button is held
 //ANI: Is the desired animation when the button is released
 //KEY: Is the key that will need to be held
 //FRAME: Is the frame that will repeat
 //LIMIT: Is how much time the button need to be held

	void self	= getlocalvar("self");
	int iPIndex	= getentityproperty(self,"playerindex");
	float time	= openborvariant("elapsed_time");

	if(playerkeys(iPIndex, 0, key)){
		if(getlocalvar("charge") == NULL()){
			setlocalvar("charge", time+limit);
		}
		updateframe(self, frame);
	}
	else
	{
		if(getlocalvar("charge") != NULL()){
			if(time > getlocalvar("charge")){
				performattack(self, openborconstant(ani), 1);
				setlocalvar("charge", NULL());
			}
		}
	}
}

In resume, as soon the animation reaches frame 2, the keyCharge script will check if the correct key is held and will repeat the desired frame. If the limit is reached and the button is released, the desired animation will be performed. If the button was released but the limit isn't reached, the current animation will end normally, in this case, the "attack1" animation.

Note that you can't move the character until the button is released because will enter in a loop in the current animation. To work like the SOR charge attack and move freely, you will need a keyscript event, a bit more complicated. Please let me know if it worked before we can go to keyscripts.
 
Kratus: Ok, I added the script to player.c. For the moment, the keycharge block the anim to punch2.gif :
Code:
anim	attack1 #Punch
	delay	8
	offset	42 110
	bbox 30 6 27 104
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A2" 0
	sound	data/sounds/punch.wav
	frame	data/chars/karatedo/punch1.gif
	frame	data/chars/karatedo/punch2.gif
	@cmd keyCharge "ANI_FREESPECIAL21" "attack" 1 100
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/punch2.gif
	frame	data/chars/karatedo/punch1.gif

Anim freespecial21 is the charge animation and anim chargeattack the attack when the button is released:
Code:
anim freespecial21 #Charge
	offset	44 102
	bbox 26 2 32 100
	delay	3
	sound	data/sounds/yossha.wav
	frame	data/chars/karatedo/chargingpunch1.gif
	frame	data/chars/karatedo/chargingpunch2.gif
	frame	data/chars/karatedo/chargingpunch3.gif

Code:
anim chargeattack
	offset	44 104
	bbox 26 4 32 100
	chargetime	0.4
	delay 13
	frame	data/chars/karatedo/chargepunch1.gif
	attack5 42 0 45 42 10 1 1 0 0 0
	frame	data/chars/karatedo/chargepunch2.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	attack5 81 12 40 42 10 1 1 0 0 0
	sound	data/sounds/yossha.wav
	@cmd	dasher 1 0 0 1
	frame	data/chars/karatedo/chargepunch3.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	attack5 80 26 30 38 10 1 0 0 0 0
	frame	data/chars/karatedo/chargepunch4.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	@cmd	stop
	frame	data/chars/karatedo/chargepunch5.gif

I let you test ingame here:
https://www.dropbox.com/sh/w1kesbeeddj9u1z/AABSjDSxGj2adz9IzEKjHxDla?dl=0
Thanks, I've got something for your game and will release it soon ;).




 
kimono
I made some changes in the previous scripts:

- updated your keyall.c with a script to detect held keys
Code:
//Charge attack
    if(iAttackH){ //Attack is held?
      setglobalvar("keyHeld", openborvariant("elapsed_time"));
    } else { //Attack is not held?
      setglobalvar("keyHeld", NULL());
    }

- updated the keyCharge script, and added the "keyLoop" and "anichange" scripts
Code:
void keyCharge(void ani, float limit)
{//Perform a custom charge attack when a defined button is held
 //ANI: Is the desired animation when the button is released
 //LIMIT: Is how much time the button need to be held

	void self	= getlocalvar("self");
	int iPIndex	= getentityproperty(self,"playerindex");
	float time	= openborvariant("elapsed_time");

  if(time > getglobalvar("keyHeld")+limit){
    executeanimation(self, openborconstant(ani), 1);
  }
}

void keyLoop(void key, int frame)
{//Loops defined frame if defined key is held
	void self 	= getlocalvar("self");
	int iPIndex = getentityproperty(self,"playerindex");

	if(playerkeys(iPIndex, 0, key)){updateframe(self, frame);}
}

void aniChange(int type, void ani)
{//Change animations
 //Type 0: Default animation changer
 //Type 1: Execute animation changer
 //Type 2: Performattack animation changer
	void self = getlocalvar("self");

    if(type == 0){changeentityproperty(self, "animation", openborconstant(ani));}
	  if(type == 1){executeanimation(self, openborconstant(ani), 1);}
  	if(type == 2){performattack(self, openborconstant(ani), 1);}
}

- updated the following animations
Code:
anim	attack1 #Punch
	delay	8
	offset	42 110
	bbox 30 6 27 104
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A2" 0
	sound	data/sounds/punch.wav
	frame	data/chars/karatedo/punch1.gif
	frame	data/chars/karatedo/punch2.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/punch2.gif
	@cmd keyCharge "ANI_FREESPECIAL21" 79.999 #THE DELAY USED TO CHECK IF THE ATTACK KEY IS HELD FROM THE FIRST TO THE LAST FRAME
	frame	data/chars/karatedo/punch1.gif

anim freespecial21 #Charge
	offset	44 102
	bbox 26 2 32 100
	delay	3
	sound	data/sounds/yossha.wav
	frame	data/chars/karatedo/chargingpunch1.gif
	frame	data/chars/karatedo/chargingpunch2.gif
	frame	data/chars/karatedo/chargingpunch3.gif
	@cmd keyLoop "attack" 1
	@cmd aniChange 2 "ANI_FREESPECIAL22"
	frame	data/chars/karatedo/chargingpunch3.gif
	
anim freespecial22 #Charge attack
	offset	44 104
	bbox 26 4 32 100
	chargetime	0.4
	delay 13
	frame	data/chars/karatedo/chargepunch1.gif
	attack5 42 0 45 42 10 1 1 0 0 0
	frame	data/chars/karatedo/chargepunch2.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	attack5 81 12 40 42 10 1 1 0 0 0
	sound	data/sounds/yossha.wav
	@cmd	dasher 1 0 0 1
	frame	data/chars/karatedo/chargepunch3.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	attack5 80 26 30 38 10 1 0 0 0 0
	frame	data/chars/karatedo/chargepunch4.gif
	attack5 0 0 0 0 0 0 0 0 0 0
	@cmd	stop
	frame	data/chars/karatedo/chargepunch5.gif

anim chargeattack #Used to disable the default engine charge attack
	chargetime 9999
	offset	44 104
	delay 4
	frame	data/chars/karatedo/chargepunch1.gif

Now I understand better what you want. I thought that you want to go to the charge attack directly from the attack1 animation, but you want an additional animation to show the charge before the attack is performed.

What each script does:

KEYALL: Will detect the held key and will save tue current time
KEYCHARGE: Will calculate the delay between the previous registered time and the current time. If the desired delay is reached, the character will go to the "charge" animation
KEYLOOP: Will repeat the desired frame while the defined button is held
ANICHANGE: If the attack key is released, the keyLoop will not be executed and the aniChange will perform the "ANI_FREESPECIAL22" animation

NOTE: I suggest to not use the "chargeattack" animation to not cause conflicts with the scripted version. To disable it, all you need to do is to defined the chargetime to a high value inside the "chargeattack" animation. Thanks to pudu that suggested me this idea in SOR2X

Here's the updated game file:
https://drive.google.com/file/d/1hI_Evs5444Z7X1DFgxLktUHfXydsW3bq/view?usp=sharing
 
Yes, if you use an animated charge attack, it will be used together with the key press script. There will be 2 kinds of hold down attacks. Kratus is correct. I have done a lot of tests before, and only one of them can be banned in order to perfectly use the charge attack. :) :) :)
 
Thanks Kratus and pudu, this works perfectly. I will just try to make the same for a kick charge attack. I used previously anim chargeattack because I haven't got other functions to use this charging move. I won't use harcoded chargeattack anymore if I don't need it.

One last thing: I use a double attack (freespecial9) with kick and punch activated with a keyint in basic punch or kick like this:
DyysvSS.png

Code:
anim	attack1 #Punch
	delay	8
	offset	42 110
	bbox 30 6 27 104
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A2" 0
	sound	data/sounds/punch.wav
	frame	data/chars/karatedo/punch1.gif
	frame	data/chars/karatedo/punch2.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 67 19 59 23 8 0 0 0 0 0
	frame	data/chars/karatedo/punch3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/punch2.gif
	@cmd keyCharge "ANI_FREESPECIAL21" 79.999 #THE DELAY USED TO CHECK IF THE ATTACK KEY IS HELD FROM THE FIRST TO THE LAST FRAME
	frame	data/chars/karatedo/punch1.gif

anim	freespecial #Kick
	delay	8
	offset	61 110
	bbox 48 8 26 102
	@cmd	keyint "ANI_FREESPECIAL9" 0 "A" 0
	sound	data/sounds/kick.wav
	frame	data/chars/karatedo/kick1.gif
	frame	data/chars/karatedo/kick2.gif
	attack1 68 33 70 20 10 0 0 0 0 0
	frame	data/chars/karatedo/kick3.gif
	attack1 0 0 0 0 0 0 0 0 0 0
	frame	data/chars/karatedo/kick2.gif
	frame	data/chars/karatedo/kick1.gif

Do you think it's a good way to activate this double attack?
 
kimono Yes, usually the anim chargeattack of the engine is not very easy to use, but it is very good to use the script to hold down, and you can also perform multiple stages and multiple charge attacks, it depends on your idea. My "kunioLA" is also a charged attack script using SOR2X.
I think your approach is very good. :) :) :)
 
Thank you pudu, I'll test your Kunio game and give you feedback. I hope that one day my Kunio-Kun (as Marian) arcade sprites will find a place in a Openbor game too :).
 
Hi, I am a beginner, I am developing my mod. I found this post that talks about something that is equal to what I want to implement, but I am a beginner at using scripts. Could you help me? What are the scripts that I must modify to achieve this of loading by pressing the button?
Thanks.
 
Hello again and thanks kimono, I did not know if I should post here or open a new post. I've been following the steps of Kratus, but I don't think I have the necessary knowledge about scripts yet (although I have already managed to implement a couple of them successfully in my Mod)

My first problem is when I add Keyall.c in the scripts folder, OpenBOR crash, when I do that.
I'm sure I have to activate it somewhere so that this doesn't happen, maybe create a Scripts.txt file in the Data folder?

Thanks :D

 
Back
Top Bottom