Tutorial Fighter (updated 9/15/10)

This forum is currently in read-only mode.
  • I have to agree with the others, this is great and it's awesome that you take time to do this tutorial.

    Hah, I initially wrote special moves for Part 4 but then took it off because it would be really tough

    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

  • Minor thread hi-jack:

    I actually sat down just now to test out a theory. http://www.box.net/shared/9m90tzyf7e

    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.

  • Thanks =)

    The first one you mentioned: you can just hold down and back and get the attack.

    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.

  • Ah ok, I understand what you did with branching now. Very creative solution!

    but it's comparing the array which puzzles me

    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.

  • 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.

    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?)

  • 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.

    This would require us to run multiple loops to differentiate between different attacks

    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?

    Maybe we should start a specific thread for this one issue so that your tutorial thread doesn't get bogged down more by this?

    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.

  • 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.

  • 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.

  • 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.

  • It's basically the same as UberLou's with a timestamp.

    I'll try and do a timestamped example.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • PART 2: CONTROLLING THE PLAYER

    Download tutorial file

    Changes from Part 1

    • Scaled collision box to better represent the player
    • Added enemy sprite to "character" event sheet
    • Press 1 to spawn a new enemy
    • Organization, made folders for each character
    • Moved the code to hide "solids" layer into the "system" event sheet

    New Player Variables:

    • hbSpawner: used to spawn a hit box when it reaches a certain time

    Global Variables:

    • hitPause: used for the hit pause effect when you successfully attack an enemy

    Layouts and Event Sheets

    • FXnStuff Layout: For...effects...and stuff
    • Enemy01 Event Sheet: This event sheet contains all of the enemy code
    • System Event Sheet: This sheet is for global game systems. Stuff like controlling particle effects, hitpause, camera shake, debug, etc.

    Hit Boxes

    When you press an attack button, you spawn a hit box. This is the thing that collides with the enemy's mask or collision box to register a hit. Hit boxes store attack data like damage (how much to subtract from enemy health) or force (how much x and y translation). When the hit box collides with the enemy, the hit box is destroyed to prevent hitting multiple times. If you want multiple hits just keep spawning hit boxes like in the punch3 code of the "player" event sheet (Line 41 and 42). The "dir" variable shows its usefulness here as I can use it to scale the hit box width in the negative direction if the player is facing left. Variable "hbSpawner" is used under the animation controls section to create the hit box. I don't usually like to put anything but animation specific code under here, but I made an exception for the hit box code. It just fit neatly in there.

    Hit Pause

    Hit pause is something most action games use to make attacks feel powerful. When an attack connects, there is a short pause in the game to freeze frame the action. The heavier the attack, the longer the pause. It also offers the player a split second to think about what they want to do next. Try longer hit pause timings for a more dramatic effect.

    Hit Effects

    I like to make my own particle effect systems in Construct for VRAM optimization and greater control. It's more optimized for VRAM because you can use one sprite for different systems. You also get more control because each particle is an object. All code for the particle effect is in the "system" event sheet.

    Again, if there are any questions or something needs to be explained more clearly please let me know and I'll update the post.

  • TUTORIAL FIGHTER!

    <img src="http://www.louisferina.com/games/TutorialFighter/TutFighter.jpg">

    INTRO

    Tutorial Fighter will be a series of tutorials aimed at moderate to intermediate level Construct users showing how to make an action game. I'm expecting each part of the tutorial to be continuously evolving. I will explain what I think is necessary, but if there are questions or I missed something, I'll make sure to add them into the main post or into the comments of the cap file. If you have any suggestions on how to make these tutorials any better, let me know. Help me help you!

    I am not a programmer and I don't claim this as the definitive way to make an action game in Construct. If anyone has any suggestions for better coding, I am open to them. I am also not a game designer. If I've incorrectly explained any concepts or someone can define them more clearly, feel free to correct me and I'll update my post.

    Also, please excuse my crappy graphics, I plan to polish them as I go. OK, enough disclaimers, here we go!

    • PART 1: CONTROLLING THE PLAYER Covers player control and attacks.
    • PART 2: HITTING THINGS Adding in hit boxes, enemy hit reacts, hit pause, hit effects etc.
    • PART 3: MORE PLAYER MOVEMENT Adding more actions for the player: running, running attacks, blocking, dodges
    • PART 4: SPECIAL MOVES inkBot created a nice example of how to do special moves based on discussions on page 3. I haven't gotten to implementing a special move system yet, but check it out if you're interested.

    Enjoy!

    -Lou

    I am an game desginer + i can do graphical art aswell, & i simple love this way of style of fighting, we should make this game as an team

  • nice update.

  • hey how can i open it? is it cuz i have a new version.

    where can i get the new version??

    thanks!

  • You can open it with Construct 1. Sorry, I'm not really supporting this anymore since I've moved onto Construct 2. The concepts are exactly the same though so you should be able to rebuild it in 2.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)