Fighting Game Demo

Here is a log of a fighting game being created.

Room 1 (Title Screen)-
Background image. Start button. Click start, go to the next room which is character select for now

Room 2(Character select) –
Some pictures of Ryus face to represent buttons you can click to change your character. IDea will be clicking each one changes your dude

Room 3 (Battle screen) –
You fight here. Right now it just draws RYU which will be the test player.


Goal here won’t be to clone SF2. I have never made a fighting game and will be making things up as I see fit for no reason.
I am going to concentrate a lot early on on some type of system to make fighters for me.

First order of business I will probably make a sprite that contains all frames of a fighter. Then I would like to have an editor in my game that prints out all of my frames. There I will define for each ‘frame’ all hitboxes where the character can take damage from (red) and all hit boxes that deal damage to other players (Green) quickly.
Also, I think there will be a few states that will need to be defined per frame as well.
some off the top of my head
1.) Resistance. if you are blocking then you will take less dmg and less knock back
2.) invulnerability. If ryu dragon punches he’s basically a god
3.) Can you attack? Things like this will be, are you getting up? are you falling down? Are you mid attack? are you stunned? etc

So every ‘frame’ in my animation will be treated as an object that is a state of my character.
so if my L Punch is 3 frames. I can’t be in the middle of that animation and just do a completely different move. Or…can I? hehehe

I created an ingame screen where I can create my fighter and print out the code and plop that into an instance.

There are some buttons on the side.
Clicking next frame cycles through all the animations of my character. There I can draw with my mouse a box around him.
When I click ‘set box’ it makes it a permanent part of his character.
I can click ‘hitbox type inc’ and it will increment the type of box im going to draw.
right now there are 3 options
0 -> his hitbox for getting hurt
1 -> his hitbox for doing damage
3 -> his grab box which is not drawn yet.

effectively I want to draw in real time all the hitboxes really quick rather that coding myself X1,x2,y1,y2 box properties and the X Y in space positions.
Once I am done I click print code. and it prints

That’s just my character after I generated his hitboxes doing his idle animations

So far you can idle standing.
walk left and right
punch on the ground.
punch in the air.
if you are pressing left/right while you jump you’ll go that direction.
right now you can change direction mid-air. woops.

Right now every frame has 2 lookup tables.
Based on the animation frame index, it pulls whether or not you can attack on that frame and how long the animations last.
Since the screen is 60FPS, if my animation has 2 sprites the table looks like this
frameAnimationCount[0] = 20;
frameAnimationCount[1] = 10;
frameAnimationCount[2] = -1;
So 20 out of the 60FPS is on frame 0, and 10 of that is on frame 1. when it gets to -1 it resets.
// can you attack? 0 is yes
canAttack[0] = 0;
canAttack[1] = 0;
canAttack[2] = 0;

Since those 2 frames are my ‘idle’ animation, I can attack on any of those frames.
If I am attacking, I cannot attack again until the animaton cycle plays out.
There are some flags that determine when you jump, if you are in the air, and if you have landed. Those all come into play on whether or not you can do a thing.
If you jump and attack, you can attack once until you’ve landed. You can not jump again until you land either.


stop hitting yourself!!
When someone gets hit they enter ‘im getting hit’ animation. right now its just one animation no matter what. In actual fighting games, at least I can only guess, they have hit animations for being crouched and in the air. and different types of hits too.
The way this game will work is when you get hit, you will increment a damage threshhold counter. and you can keep getting hit and taking damage, until you hit the threshold and that will be considered a knock down or something, where iframes come in so that players can’t perma-juggle you.


I am not clear how counters work in fighting games so I’m not sure how i’ll enter that.


Each frame has many more properties to set (and more to come)


Damage will indicate how much dmg your green boxes are doing on that frame. If I wanted to have say 2 fists doing 2 different DMG then I’d need to tweak that around.
Are you taking dmg? falling? crouching? invulnerable? etc. lots of flags to set.
I’ve added a few more. for example, the combo needed to begin the move, will be set on the first frame of the moves animation.



Here I added an X and Y modifier. If you think about ryus spinning kick, each frame he increments some amount on the X axis, so this is where it comes into play. I did an example of lightpunch moving me a bit.


some interesting stuff here.
you can punch while standing, crouching or jumping. does a different punch
you can jump standing still or run and jump doing the little spin.
I can have a lot of fun with the X / Y modifiers.
whenin the air and he goes for a light punch he sorta pauses and then sharply shoots out
kinda cool

every attack has a knock back value

every frame has a knock back resistance, so i set idle to be 90% (imagine blocking..)


you can see how it doesnt move now
cant forget Y axis knockback




New frame property called damage threshold.
When you hit a player they get knocked back, notice the first hit in the GIF his hitboxes are still there.
When The guy on the right throws a punch, the punch has a threshold of 51%. When your hit applys it will increase the opponents damage threshold by that much. Once its greater than 100%, the damage threshold has been set.
This might be where you set it to knock the opponent down.
Notice how when I hit him twice in a row, he gets iFrames meaning he’s invulnerable. So his red hitboxes are gone.

There is a global varaible that will determine how many ‘frames’ pass until the threshold is reset. This means how many frames until your ‘combo’ is no longer a combo. Preferably meaning that after the hit you gave to your opponent he has had time to fully recover. This sort of stops perma-chain combos.
When designing moves it will be interesting to consider knock ups, knock backs, thresholds and damage.
Some moves might be fast long range and low threshold but low damage. So it could be used to connect other moves effectively and keep a combo going. lol.

Some more detail on the way hitting someone works which came in to play here.
If I throw a light punch which is 3 frames, each frame in the animation might actually be 10 of my 60 frames per second each.
That means when I throw a light punch, the frame that actually has the hitbox to do damage (Green) might hit the enemy player on each frame (10 times). One way might be to make the enemy invulnerable. Another way might be to remove the guy hittings hit box that does the damage. So that only damage is applied once. But I’m thinking what do you do ina multiplayer setting? In smash I think you can get juggled around by 2 players. But moves only apply damage once.
How it works is there is a global counter that is called attackID. Whenever an attack is started, it creates an attackID locally, based on the globalID. This makes sure it is a unique ID. When the attack damage is applied we have a list on the player taking the damage that determines if this attacks damage has been applied or not already to this character.
That way I can make sure that whichever frame out of my 10 frames of damage connects, if its more than one, it applys the damage only once. But it also makes sure that if there are 4 players. More people can still do damage to this player.

Think of it this way
Player 1 throws the first attack in the game, light punch. Global attack counter is 1. So his light punch attack ID is 1.
Player 2 gets hit by this damage. He has a list of IDs he has taken damage from. So far nothing. So his list becomes
List :
1

When the next frame comes in the game, player 1 is still in the middle of his light punch hitting player 2, however when it goes to apply damage it says
List
1
This list already has the light punch damage applied, so we don’t do it again.

If on this frame player 3 comes, and throws the second attack in the game, light kick, the global attack ID is now 2, so its attack ID is 2. We can still go ahead and apply that damage to player 2 in the same way, knowing he has yet to be hit by that.

Damage from all players will apply to the threshold. So if player 1 and 3 beat up on 2, eventually he’ll get the iframes to ‘recover’.



I guess one thing to consider is what happens if player 2 recovers and on the frame he can attack again, he gets hit again into another combo? This is sort of where counters or reverses come into play.
In SF2, ryu can immediately dragon punch on the same frame he recovers if you time it right (I think) which makes him invulnerable when he gets up. So I’ll need to design the attack orders in a way that the last frame of the knock down, or recovery allows the player to ‘attack’. So you go from that iFrame state, to an attack state on the next frame. if timed correctly.
This is already sort of designed where every frame has a ‘can attack’.



so if ryu is invulnerable getting hit for 4 animations. Where each unique frame lasts for 10 frames on the screen.
If we set the 4th and last frame to allow him to attack, that means the player has 10/60th of a second to execute something, to go from that invulnerable state, to an attack state.


however if you go into a light punch think of this, the first frame, 10/60th of a second, you don’t actually have a damage hitbox so you aren’t really countering.

So if you go from an invulnerable frame, to a light punch, and a player is mid-attack on your character you just entered the first frame of light punch, where you can get hit, and are not applying anything back to your opponent so you’ll just get hit again lol.


if red hitboxes hurt opponents, player on the right his trying to hit player 2, who is currently invulnerable.
Greenhitboxes represent where you can take damage

Player on the left goes for a light punch, first frame is like this

He can take damage, and is not doing any damage yet. So he’ll get hit by the light punch in progress

but if on recovery you dragon punch, you won’t have any green hitboxes for a few frames

allowing you to connect damage to that player, and counter

ish

I don’t play fighting games or ‘know’ the mechanics but thats my 2 cents

networking!

Left side is the server. I’m a goofball and all characters move from the same server input LOL.
Server shows the red and white people because theres 2 people in the game.
They have a weird double effect. that’s because its actually drawing my guys twice because i’m dumb and you can ignore it.
on the right side its the client. mimicing the server.

In a few minutes here, how its going to work is, the client side only sends keyboard inputs. And the server takes that and moves the proper characters. The server returns all of the graphical information to the clients after doing all the processing.

the code to take and read the client input is there I haven’t tied it back to the instance though.


you don’t need to really be able to read code to understand whats going on.
two computers. One has a server and client object running.
Another has a client object only.

The server object takes all of the characters, and packs the information the client needs to draw into packets each frame.

server X -> client X
server Y -> client Y

ez.

client takes all that data and draws it to the screen

so for everyone playing at home, server broadcasts the data for client, client reads the data, client uses that data to draw.

Now the client, all it has to do is send the key data to the server. What key, and what state is it in?

The server uses that data to do all the calculations it needs to then send all that data back to the client.

No more ‘duplicate’ drawing of sprites + adding player names.


Leave a Reply

Your email address will not be published. Required fields are marked *