Throwing in MUGEN
Throws exist since the original Street Fighter 2 and they were an "easy" way to inflict damage to your opponent, since you only needed to be near him and push the controller forward plus a punch or kick button to throw him. They were called cheap sometimes .but in truth there are chars that rely heavily on the use of throws or "special throws" (aka "command throws" that require a special motion to be executed) to win, like Zangief and his Spinning PileDriver. In this section you will hopefully learn how to implement throws in MUGEN.
Example: Chris (Chris by Neogouki)
Neogouki's Chris throwing Geese Howard
As in every move in MUGEN, you add the proper frames to the sprite file and then define a command to activate it.
Defining how to activate the throw - The CMD File
; Aerial drop [State -1] type = ChangeState value = 850 trigger1 = command = "holdfwd" trigger1 = command = "b" trigger1 = Var1 = 0 trigger1 = statetype = S trigger1 = stateno != 100 trigger1 = P2bodydist X <= 10 trigger1 = P2movetype != H trigger1 = ctrl = 1
|
Chris's Aerial Drop is what is called "a normal throw". We already said before that normal throws require that you are fairly close to the opponent , and that you press forward plus some button to actually throw him. This "conditions" are defined in the CMD file:
a) Pressing forward + some button
trigger1 = command = holdfwd
trigger1 = command = b
The above triggers ,that have the same number (1) check that the player has pressed forward and in this case, the "b" button.
b) Checking the distance
trigger1 = P2bodydist X <= 10
The BodyDist trigger lets us know how far away is the opponent. In the above example we check that the opponent is no more than 10 pixels away from us.
c) Other checks
As always, we check that the player is standing:
trigger1 = statetype = S
...and is capable of doing moves (not receiving hits,falling,etc)
trigger1 = ctrl = 1
In this case, we also must check that the player is not running towards the opponent (generally you must be standing near the opponent,not running to make the throw work) :
trigger1 = stateno != 100
We can't let the player throw the opponent if the opponent is reeling from a hit, so we check that the enemy is not in a "gethit state"
trigger1 = P2movetype != H
Of course, if you do want to let the player combo the throw (that is, throwing the opponent while he's reeling from previous hits) , just don't add the above trigger and you will be able to do some Alpha3-like throw combos.
That's it for the CMD file, once the player has met all conditions we let him do the throw,so now we go where the actual throw is implemented.
Implementing the throw: the CNS File
; Aerial drop (attempt) [Statedef 850] type = S movetype = A physics = S anim = 850 velset = 0,0 ctrl = 0
[State 850, 1] type = HitDef trigger1 = AnimElem = 1 attr = S, NT priority = 2, miss sparkno = -1 snap = 32,0,0,1 p1stateno = 860 p2stateno = 870
[State 850, 2] type = ChangeState trigger1 = AnimTime = 0 value = 0 ctrl = 1 |
This is the main part of the throw, first we tell MUGEN that we are going to use animation number 850 for this throws.
[Statedef 850]
type = S
movetype = A
physics = S
anim = 850
velset = 0,0
ctrl = 0
animation no.850
In the above picture, taken from Ranchan's Mugenerator, you should note that the red collision box is slightly to the right of Chris. This area, marked by the red box, is what you would call "the throw area" . When the enemy touches this area, he will be thrown. This is called the "throw range" in most fighting games, so when you want that your char has a long "throw range", just make his collision box wider,and don't forget to draw it out of your character,not surrounding your character. The above pic should be enough as reference.
Ok, now we define how the throw will "hit" the opponent. As in every move in MUGEN, we use the HitDef controller to do this:
[State 850, 1]
type = HitDef
trigger1 = AnimElem = 1 <-------the throw will be activated in the first frame of its animation
attr = S, NT <------ this move is a Standing,NormalThrow (S,NT)
priority = 2, miss <------ default priority is 4,Hit ,using 2,miss gives the throw less prority than
other moves, so the throw won't be "invincible".
sparkno = -1
snap = 32,0,0,1 <------ put the opponent in this position when hit
p1stateno = 860 <------ When throwing, Chris will go into state 860
p2stateno = 870 <------ and his opponent into state 870 (more on this later)
After Chris throws the opponent and his animation ends (Animtime=0),we must return him to his standing state (State 0),to let him make more moves:
[State 850, 2]
type = ChangeState
trigger1 = AnimTime = 0
value = 0
ctrl = 1
We have defined the throw, but now is time to code what exactly is Chris going to do while throwing, and how the opponent will react to this. As we have said before, state 860 explains what Chris behaviour is going to be (p1stateno = 860) and 870, his opponent's (p2stateno = 870)
State 860: Chris throwing the opponent
; Aerial drop (success) [Statedef 860] type = S movetype = A physics = S anim = 860
[State 860, 1] type = NotHitBy trigger1 = Time = 0 value = SCA time = 81
[State 860, 2] type = PlayerPush trigger1 = Time >= 0 value = 0
[State 860, 3] type = Explod trigger1 = AnimElem = 2 anim = 880 sprpriority = 0 postype = p1 pos = 56,-76 bindtime = 1
[State 860, 4] type = PlaySnd trigger1 = AnimElem = 2, = 1 value = 1500,1
[State 860, 5] type = TargetBind trigger1 = AnimElem = 4, >= 0 trigger1 = AnimElem = 5, < 0 pos = 20,0
[State 860, 6] type = TargetBind trigger1 = AnimElem = 5, >= 0 trigger1 = AnimElem = 6, < 0 pos = 42,-64
[State 860, 7] type = TargetBind trigger1 = AnimElem = 6, >= 0 trigger1 = AnimElem = 7, < 0 pos = 30,-52
[State 860, 8] type = TargetBind trigger1 = AnimElem = 7, >= 0 trigger1 = AnimElem = 8, < 0 pos = 22,-58
[State 860, 9] type = TargetBind trigger1 = AnimElem = 8, >= 0 trigger1 = AnimElem = 9, < 0 pos = 2,-60
[State 860, 10] type = TargetBind trigger1 = AnimElem = 9, >= 0 trigger1 = AnimElem = 10, < 0 pos = -26,-50
[State 860, 11] type = TargetBind trigger1 = AnimElem = 10 pos = -26,-110
[State 860, 12] type = TargetState trigger1 = AnimElem = 10, = 1 value = 880
[State 860, 13] type = PlaySnd trigger1 = AnimElem = 10, = 1 value = 850,0
[State 860, 14] type = PlaySnd trigger1 = AnimElem = 10, = 3 value = 240,1
[State 860, 15] type = ChangeState trigger1 = AnimTime = 0 value = 0 ctrl = 1 |
Wow, that was a lot of code. Fortunately, a lot of lines seem similar,and they do cause they do the same thing.
We will look at the code by part beginning with:
-Defining the animation
; Aerial drop (success)
[Statedef 860]
type = S
movetype = A
physics = S
anim = 860
Standard stuff here, we define the move and tell wich frames of the SFF file we will use for the throws. Like it says above, we will use animation number 860 (anim=860).
animation no.860: Chris's Aerial Drop
-Making your char invulnerable during the throw - NotHitBy
[State 860, 1]
type = NotHitBy
trigger1 = Time = 0
value = SCA
time = 81
In the first part of the state, we find the NotHitBy controller, this lets your player be invulnerable to the attacks of his opponent. It takes two parameter ,how long will the effect last (time=81) in game ticks (1 sec=60 game ticks), and which moves will the player be invincible to : (value=SCA) meaning he 's invulnerable to StandingCrouchingAerial attacks while he's throwing the other guy.
-Putting your Sprite "overlap" the opponent - PlayerPush
[State 860, 2]
type = PlayerPush
trigger1 = Time >= 0
value = 0
Next,we have the PlayerPush controller. As you probably have seen in most fighting games, when you throw someone, their sprites overlap , meaning they are in top of each other, giving the illusion that the character is indeed putting its hands on the opponent's clothing. That's what we use the PlayerPush for. See the following pic for reference:
PlayerPush controller: Chris's sprite "on top" of Geese's
- Using custom sparks when throwing- Explods
[State 860, 3]
type = Explod
trigger1 = AnimElem = 2
anim = 880
sprpriority = 0
postype = p1
pos = 56,-76
bindtime = 1
In the third part of this state, another cool controller appears: Explod. Explods will be explained more thoroughly soon in this tutorial, but for now, you should now that it lets you put sprites in the screen that are not either of the players neither are helpers. Want to set the enemy in flames? Find some flame sprites the put them on top of him with Explods. Want to have a portrait of your char behind him,when he does his super? ,use Explods . Want to make the screen "explode" when you kill someone with a super? That's right,use Explods.
Any sprite you need that is not the main char can be put with Explods, and in this case we need Explod because Chris uses a custom spark when he "catches" the opponent with his throw.
Chris using a custom spark while throwing
Like I said, Explods sintax will be explained in other section,but for now take a look at the code above and you should be able to discern that the spark is going to use animation no.880 of the SFF file (anim=880) and it's goint to be positionate in the screen at coordinates 56,-76 (pos = 56,-76). That's all you need to know in this case.
anim 880: Custom spark for Chris's throw
-Binding your opponent to your char -TargetBind
[State 860, 5]
type = TargetBind
trigger1 = AnimElem = 4, >= 0
trigger1 = AnimElem = 5, < 0
pos = 20,0
....................................
....................................
[State 860, 11]
type = TargetBind
trigger1 = AnimElem = 10
pos = -26,-110
Now comes the important part of the throw. In order to give the illusion that your char is throwing the opponet over his shoulder as Ryu does , or in this case hitting him with Chris legs to make him fly, you have to "bind" him to your chars position. This is done by using the TargetBind controller. You can specify how long the effect will last, this is specified in game ticks as is always the case with tame in MUGEN. If you don't specify the "time=" parameter it defaults to 1.
The pos argument specifies the offset from Chris axis to which the opponent will be binded. These values are difficult to get right in your first try, so it's very possibly that you will have to play with them a bit and trial and error till you are satisfied with the results.
- Changing the opponent's states - TargetState
[State 860, 12]
type = TargetState
trigger1 = AnimElem = 10, = 1
value = 880
We have already thrown the enemy with the previous states, but now we want him flying in the air, but he won't do it alone!, we can use the TargetState controller, that lets you change in which state is our opponent now (this only works if we have previously binded him with TargetBind), so when the animation reaches its 10th frame (Animelem=10) , we change him to state 880 to make him fly (TargetState with value=880).
Animelem=10:Chris launching the opponent into the air
State 870: State for the opponent while being thrown
; Thrown by Aerial drop [Statedef 870] type = S movetype = H physics = S velset = 0,0 ctrl = 0
[State 870, 1] type = ChangeAnim2 trigger1 = Time = 0 value = 870
[State 870, 2] type = NotHitBy trigger1 = Time = 0 value = SCA time = 35
[State 870, 3] type = SprPriority trigger1 = Time = 0 value = -2
|
As seen previously , State 870 is the state we put the opponent in as soon as the throw makes contact, and BEFORE we go into state 880 that makes hin fly into the Air and land.
[State 870, 1]
type = ChangeAnim2
trigger1 = Time = 0
value = 870
Here we make the opponent use animation 870 of Chris 's AIR file. The AIR file, as you know, contains all the animation information including position of each animation frame in the screen, how long to show each frame,etc. Because Chris knows how his throw works and his opponents don't , we just let them use our AIR file for this state so they know how to show their frames while being thrown. This is about the only case where you are going to use ChangeAnim2.
animation no.870: being thrown
Please note that we let them use our animation data,not our frames,ok? We give them the information of where each frame goes, how long to show them,etc. But the opponent is going to use their own frames. Hope that clears up any doubts.
[State 870, 2]
type = NotHitBy
trigger1 = Time = 0
value = SCA
time = 35
Now we use the NotHitBy controller again, this lets your player be invulnerable to the attacks of his opponent. It takes two parameter ,how long will the effect last (time=35) in game ticks (1 sec=60 game ticks), and which moves will the player be invincible to : (value=SCA) meaning he 's invulnerable to StandingCrouchingAerial attacks. As this is the state of the opponent (remember? State 870 defines what the opponent is going to do while being thrown), the above code renders the opponent invulnerable to further attacks for 35 game ticks or half a second, aprox.
Of course you can eliminate this in your char, especially if you want to juggle your enemy after throwing them or something like that. Like I always say: this are merely guidelines from tried and true characters, but you can (and should) be as creative as u want.
-State 880: Making your opponent fly (and land too!)
; Thrown by Aerial drop (in the air) (in the air) [Statedef 880] type = A movetype = H physics = N
[State 880, 1] type = VelSet trigger1 = Time = 0 x = 2.3 y = -7
[State 880, 2] type = VelAdd trigger1 = Time > 0 y = .4
[State 880, 3] type = LifeAdd trigger1 = Time = 0 value = -150
[State 880, 4] type = PosAdd trigger1 = Time = 3 x = 10
[State 880, 5] type = SelfState trigger1 = Pos Y >= 0 trigger1 = Vel Y > 0 value = 5100 <----bounce from ground into air |
The worst part has already passed. We end up here after Chris finishes his state (860) and sets his opponent to State 880 with these lines (showed here in case you don't remember):
[State 860, 12]
type = TargetState
trigger1 = AnimElem = 10, = 1
value = 880
Now we only have to make the opponent fly, so how about changing his horizontal and vertical speed?
[State 880, 1]
type = VelSet
trigger1 = Time = 0
x = 2.3
y = -7
The Velset controller lets us change the X and Y velocity of a char. Less Y velocity means going up, greater Y velocity means going down. y= -7 as a paremeter in Velset makes our char go up. The same goes for X ,the horizontal axis, a positive X makes the char go forward, a negative makes him go backward.
We can positively say that with the above parameters, the char will go forward and up,that's right? Please note that we are talking about Chris opponent here not Chris himself!. This state 880 that we are looking at now,contains the actions for the enemy , because we said that we were going to control his movements ourselves, in order to achieve greater control in how he flies into the air. We did it in Chris states with the following lines, remember?
[State 860, 12]
type = TargetState
trigger1 = AnimElem = 10, = 1
value = 880
Ok , that said , we go to our next part in state 880:
[State 880, 2]
type = VelAdd
trigger1 = Time > 0
y = .4
Here we use the VelAdd controller to make the char come down, we made him fly before, now we add to the Y velocity a positive value to make him come down (y=.4)
[State 880, 3]
type = LifeAdd
trigger1 = Time = 0
value = -150
This is nothing difficult, we just decrease our opponent's LifeBar using the LifeAdd controller with a negative value (you do know that (+) plus ( -) gives you (-) ,don't you?) : )
[State 880, 4]
type = PosAdd
trigger1 = Time = 3
x = 10
Nothing fancy here either, we use the PosAdd controller to move the opponent a little forward in order to make him fall in a position we like.
NOTE : Take into account that how you make the opponent fly into the air when thrown depends strictly on what character are you making or what effect you are trying to achieve, this is only a guideline, but you are free to be as creative as you want.
- Making your opponent land - Mugen predefined states
[State 880, 5]
type = SelfState
trigger1 = Pos Y >= 0
trigger1 = Vel Y > 0
value = 5100 <----bounce from ground into air
First we check that the opponent is "touching" the floor. If his Y position is positive (Pos Y>=0) then he's not in the air, and if his Y velocity is also positive (Vel Y>0) he is not going up,either, so he must be near the floor.
Remember when we used TargetState to make our opponent go into this state,manually? Well, SelfState lets you do the same, change to a desired state manually, but it refers to the same char,not his opponent.
So ,if State 880, the one we are looking at, is the opponent's state, then SelfState will refer to the opponent too!. In the above code we use 5100 as the parameter (value=5100), but we haven't defined a 5100 state anywhere!! In reality, there is a state 5100 for Chris, in fact: every Mugen char has it! That is cause that state comes in the Mugen engine itself, it's preprogrammed and everyone can use it.
There are a number of preprogrammed states in Mugen, if you are curious just look for the file COMMON1.CNS in the DATA directory of your Mugen installation. You will find lots of states there, and one of them will be state 5100. This state makes the char bounce from the ground into the air when they fall heavily, this adds some "drama" to the animation, and you can look at it whenever you Piledrive someone with Zangief in any SF game: your opponent doesn't just fall and stay there, they bounce back a little into the air then fall again, flat in their backs.
So, because we want this effect, we just use SelfState to change the opponent state to 5100.
That's about it, but since we have gone through *some* code I think it's time for our.....
SUMMARY
- If you are making a normal throw, check for trigger1 = command = "holdfwd" and the button designed to activate the throw. If you are making a command throw a la KOF or Zangief, specify the appropiate motion in the CMD file, this is the only difference there is. go here for a more detailed explanation
- Implement the throw itself in the CNS file. If the throw is succesful (HitDef) define 2 states ,one for your char and one for your opponent, defining the actions to be performed while the throw is active. go here for a more detailed explanation
- Now implement those 2 states mentioned earlier. Here's what Chris (our example) will do while throwing his opponent. Use of TargetBind and TargetState to "bind" the opponent to your char. go here for a more detailed explanation
- And here's what the opponent will do while being thrown.Letting the opponent use our AIR file for the throw animation data, so he knows how to show his frames while being thrown. go here for a more detailed explanation
- Implement how the throw will affect the opponent: how high is he gonna fly, how far , how fast is he gonna land,etc. Using preprogrammed State 5100 to make the opponent bounce when landing . go here for a more detailed explanation
That's it, hopefully with some work, these will inspire people to make more grapplers: go Zangief! :)