Tutorial Fighter (updated 9/15/10)

Post your own tutorials, guides and demos.

Post » Thu Aug 05, 2010 12:54 pm

Very nice tutorial! I've been meaning to create a fighting game!
B
3
S
1
G
2
Posts: 86
Reputation: 997

Post » Fri Sep 03, 2010 3:15 am

I have to agree with the others, this is great and it's awesome that you take time to do this tutorial.

[quote="UberLou":1iic7yz4]
Hah, I initially wrote special moves for Part 4 but then took it off because it would be really tough :) The thing with special moves is that, to do it right, you have to start buffering every direction. Like in Street Fighter, for Ryu's Dragon Punch its: forward,down,downforward +punch. However you can still do the motion sloppy and press: forward,downback,down,downforward, forward + punch. I guess you have to make an array, store all of the directions, and then look for combinations? Really unsure, but i'll do some research and see if I can come up with anything. Or if anyone else knows how it's done, I'd be interested in it too :)[/quote:1iic7yz4]

This is actually something I have been trying to wrap my head around for ages (ever since the TGF days) and one thing is for sure. If you're going to do it, you need tons of dedication, because making 'one' character right is a heck a task. Imagine a roster of 10-12 fighters AND decent AI on top of that.

Minor thread hi-jack:
I actually sat down just now to test out a theory. I haven't messed around with arrays at all so this is a first for me. I grabbed a Ken sprite and decided to test out making combos with arrays, and I think I got an acceptable result for something I decided to test just now. I'm planning on making a hybrid fighter in the near future so this was good practice.

You can grab the cap from here: http://www.box.net/shared/tz5kb4y71e

Edit: Uplodaded a revised version. I think this one works better. The comments are unchanged for now though, so you'll have to figure out the changes yourselves until I fix them.
New link: http://www.box.net/shared/9m90tzyf7e
B
73
S
20
G
10
Posts: 524
Reputation: 9,896

Post » Fri Sep 03, 2010 6:25 pm

[quote="inkBot":12nyboh1]Minor thread hi-jack:
I actually sat down just now to test out a theory. http://www.box.net/shared/9m90tzyf7e[/quote:12nyboh1]

Nice example inkBot! I only had a short time to look at it on my lunchbreak but I'll definitely check it out more in-depth later on. It looked like your solution was to store each input as a 0 or 1 for about 10ms and then look for a combination of inputs as being a 1? It's a cool solution but I think there could be some problems with that, though I haven't tested it out. The first one you mentioned: you can just hold down and back and get the attack. Another problem would be motions that need 2 inputs of the same direction, like double tap forward or doing 2 fireball motions for a super move.

I was thinking of a different method. You store each input into an array of size 10. (10 is just a random number right now, it should probably be larger.) So each direction is a number lets say:

neutral=0
forward=1
downforward=2
down=3
downback=4
back=5
upback=6
up=7
upforward=8

The array will be stacked with each input including neutral. So at the start your array would be filled with 0's. If you roll the joystick in a halfcircle from forward to down to back, your array would look like this:
0,0,0,0,0,1,2,3,4,5
Going back to neutral, Your array would look like this:
0,0,1,2,3,4,5,0,0,0
So you're constantly deleting the first value and registering each input as the last value. So you would store each individual input for as long as your buffer window allows. Now you would just need to look for certain patterns within the array. So if there is a 0,0,0,0,0,0,0,1,3,2 then you can do a dragon punch even if it looks like 0,0,1,0,3,2,1,0,0,0. And that dragon punch will be in memory (buffered) until the first 1 gets deleted.

Hope that makes sense. I haven't tested it out yet, but I think that is close to what's happening in fighting games.
B
77
S
49
G
24
Posts: 346
Reputation: 16,909

Post » Fri Sep 03, 2010 7:15 pm

Thanks =)

[quote="UberLou":3jikauqw]The first one you mentioned: you can just hold down and back and get the attack. [/quote:3jikauqw]
That actually no longer works in the revised version.

The way I set it up is that the movements branch out from 1 and upwards. So with the tornado kick for instance. Each direction and button has its own place in the array (except neutral). So the first command in the tornado kick combo is down, so "Down's" index is set to 1. So now we need to press down and left so we check if "Down's" index is 1, if it is 'and' we press down + left we set "DownLeft's" index to 2 and repeat. So rather than comparing against a string we're moving through a branching system. I'm not sure if it's more efficient, though I'm pretty sure it's not. It's also a "bit" more of a hassle to set up.

The way you talk about is much closer to what actual fighting games do, but it's comparing the array which puzzles me. I've never figured it out. But storing the inpputs like that and comparing it against a list of commands should be way more efficient, and with the added benefit that you can be lenient with inputs. The way I've done it requires that you get the inputs right.
B
73
S
20
G
10
Posts: 524
Reputation: 9,896

Post » Fri Sep 03, 2010 9:44 pm

Ah ok, I understand what you did with branching now. Very creative solution!
[quote="inkBot":18eacdu4]but it's comparing the array which puzzles me[/quote:18eacdu4]
I have only figured out a brute force way to find special moves in the array by using loops. I think it would work but probably not the most optimized way. For each special move you'd need a loop. So if you're looking for 1,3,2, then you just search for a 1. If thats found then search for a 3 in the remaining values then look for a 2. Then if you push punch you get the special move.
B
77
S
49
G
24
Posts: 346
Reputation: 16,909

Post » Sat Sep 04, 2010 3:08 am

[quote="UberLou":26brnkuo]I have only figured out a brute force way to find special moves in the array by using loops. I think it would work but probably not the most optimized way. For each special move you'd need a loop. So if you're looking for 1,3,2, then you just search for a 1. If thats found then search for a 3 in the remaining values then look for a 2. Then if you push punch you get the special move.[/quote:26brnkuo]

Something like this? http://www.box.net/shared/k1nqrzsx4z

I got hellbent on solving this today, almost my entire evening was spent with furrowed brows on this and came up with that solution.

It basically does what you said, but in reverse. First we look for the punch/kick button and then we go through and look for a pattern through a loop. If we do not find a pattern we stop the loop and reset our string (we use the string to compare the pattern). 0's are conveniently skipped, so the timing for the combo is set by how large our array is.

This would require us to run multiple loops to differentiate between different attacks, which might not be a good way of doing this, but I think it's the best I can think of atm. (Can you even run multiple loops simultaneously?)

(Maybe we should start a specific thread for this one issue so that your tutorial thread doesn't get bogged down more by this?)
B
73
S
20
G
10
Posts: 524
Reputation: 9,896

Post » Sat Sep 04, 2010 3:36 pm

Wow awesome, that works REALLY well! I was thinking of constantly checking for input patterns, but your method seems much more efficient to only check for it after pressing an attack button.

[quote="inkBot":3pgdf2uo]This would require us to run multiple loops to differentiate between different attacks[/quote:3pgdf2uo]

Maybe this could be done by having multiple special move strings (like your "tatsu" variable) and fill them up as you run through the one loop. I guess you would also need to figure out what was the most recent input pattern just in case there are two special moves in the buffer. Maybe it would just execute whichever move string was completed first. Not sure on that without some testing, but it seems like it could work

I haven't worked much with loops in Construct. Where does the loop increment "CtrlBuffer.CurrentX"? Is that what the "For each element" does?

[quote="inkBot":3pgdf2uo]Maybe we should start a specific thread for this one issue so that your tutorial thread doesn't get bogged down more by this?[/quote:3pgdf2uo]

I don't mind the discussion here. It is pretty relevant to the topic but it if you want to start a new thread thats cool too. When it's completed it would definitely make a good post in the Uploads section.
B
77
S
49
G
24
Posts: 346
Reputation: 16,909

Post » Sun Sep 05, 2010 10:01 pm

OK, cool. I just wanted to check if you were ok with the discussion, since it's your thread and all.

I have an update to my little test using one loop and check for each (in this case both) attacks in that loop. Earlier I tried using multiple loops. Did not work too well, and when I switched to using just one loop I got it working pretty fast.

My goal was to take two attacks with similar inputs and get them to work without interrupting each other. I thought that if I could get two similar commands to be differentiated between that would probably be the most difficult combos to differentiate between, since we can run separate loops for different button presses.

Here is the most recent version: http://www.box.net/shared/aroaui4euq
It could still be tweaked a bit to be more or less lenient in places, but I think the general idea of how it could work is solid.
B
73
S
20
G
10
Posts: 524
Reputation: 9,896

Post » Mon Sep 06, 2010 1:21 am

The circular buffer idea is how I had thought it was done.
In construct you would just have arrays with moves and one array with the current move.
Have a current index go through the current array and when comparing the moves array to the current array, start from the beginning of the moves array and from the current index in the current array, going all the way to the end, then another loop that goes from the start of the current array to just before the current index (thus scanning the whole buffer).
Each time a button or direction is registered, it's stuffed in the current move array and the index is moved. If the index goes out of bounds, it wraps around.

You could optimize this by having a separate indexer for the moves array, but that doesn't become really useful until you have a huge number of moves (like... 3 digits).

Oh and for timing, it would be better to timestamp each buffer entry. Then you could compare if the difference with the previous parsed move's timestamp fits within the move's allowed range and there you have timing.

You also could add parameters to each move, such as current distance to closest enemy to increase move variety without making them too difficult to perform.
B
3
S
2
G
4
Posts: 1,445
Reputation: 4,665

Post » Sat Sep 11, 2010 9:17 pm

Madster do you think you could make an example of the way you suggested? I fiddled about trying to do it and got nowhere. I'm going to go ahead and use my own solution, but I think yours would be much more efficient.
B
73
S
20
G
10
Posts: 524
Reputation: 9,896

PreviousNext

Return to Your tutorials & example files

Who is online

Users browsing this forum: No registered users and 0 guests