How to implement combo's in my game.

Hi :)

I am currently working on a prototype in Game Maker Studio, here is a link if you are interested:
makegamessa.com/discussion/5076/prototype#latest

I am looking to implement combo's and juggling into this game. The main character can fly and platform as well, so combo's should be executable in air and on the ground.

I have looked at this youtube video and implemented it in previous prototypes:


What I am uncertain about is:
- How do I execute a combo on an enemy and register each hit with input buffering?
- How is an enemy's hspeed and vspeed affected when I lets say perform a juggle?

Any advice and or information regarding combo's would be awesome :D

Comments

  • I didn't watch the video, but from a programmer's point of view for input buffering you can do something like this.

    [-]Make a list or an array and add each key the player presses to it
    [-]Remove the oldest item in the list after some timeout amount
    [-]After each key press check your list to see if it has a combo in it
    [-]When you detect a combo, check if there is an enemy to perform it on
    Thanked by 2Jurgen Sigh_Leeeee
  • There's of course an infinite number of ways of doing this.

    To get some cool feeling juggling, one of the tricks that many games do is have some time stutter on the hit. So the enemy that is hit temporarily pauses (and often the hitter pauses as well) so that the player has time to queue in the next attack in time to hit the enemy again. This way the player could be hitting the enemies away from them at a fair velocity, but if each attack move pretty quickly they can keep up with the enemy that they're hitting away from themselves.

    I guess I'm saying that some kind of time stutter is useful to give the player time to keep up with the action, and that way the action can happen at high velocities (instead of slowing the action down so that players can follow it).

    Don't know if that helps you at all though :/
    Thanked by 1Jurgen
  • @critic and @EvanGreenwoodl, thankyou for the input, much appreciated!

    image

    As a test, I made a cast spell when Q is check_pressed, the spell has 9 frames. obj_hit and obj_hit_last is created near the center of the spell sprite.

    if image_index == 3 || image_index == 5 || image_index == 7{
        instance_create(x,y,obj_hit);
    }
    if image_index == 9{
        instance_create(x,y,obj_hit_last);
    }


    When obj_hit collides with the demon object, the demon object's vspeed = -2 and when obj_hit last collides with obj_demon it's vspeed = 0 and it's hspeed is 30 sending the demon flying.
  • Like Evan said, there are a wide variety of ways you could implement your system, but you should obviously choose one that best suits your needs. A constrained solution will be easier to create, a more complex solution could give you more flexibility. You're solution will be somewhere in the middle.

    However, I think what you need to do is break those questions into smaller ones so you can tackle them one at a time, and once you've made a prototype for each, then combine them into a bigger project (At least that's what I did for Shattered Realms).

    - How do I make an input buffer system? (The video you posted is a good start)
    - How do I search through the buffer system to recognize correctly input moves?
    - How do I tell the game which input corresponds to which move?
    - How do I create a finite state machine? (Tutorial 1, Tutorial 2, Tutrial 3)
    - How do I cancel one move into another? (Usually during recovery frames)
    - How do I tell "moves" to listen for certain inputs, and when they recognize them, cancel into those moves?
    - How do I make a collision system using hit / hurtboxes?
    - What properties should hit / hurtboxes have and or track?
    - What are all the different states characters / enemies can have, and how do hitboxes affect them in these states.
    - If a hitbox lasts for more than 1 frame, how do I prevent it from hitting the same hurtbox twice?
    - How do I make a basic platformer? (Article)
    - How does collisions with platforms affect your hit / hurtboxes?
    - How do I incorporate (or track) hitstop and hitstun upon collision?
    - What are other people doing? (Universal Fighting Engine, ScullGirls)

    As always, understanding the terminology of a genre can help with a lot of the questions.
    Shoryuken Glossary
    Eventhubs Terminology
    (Not all of it will be relevant to your game though)

    Once you've broken down your questions like this, it's much easier to understand what you need to do, and it's also easier for people to give you more meaningful advice :D

    So pick a topic, and let's discuss it ;)
  • edited
    Hi @pieter, thanx for the input :D!
    How do I make an input buffer system?
    What I understand thusfar, is an attack has lets say 5 frames and the actual hit happens on frame 4 where the hurtbox is created. When I do a combo of lets say three moves, i would shorten each move's animation to 1 or 2 frames before the actual hit.

    I found this video on Rivals of Aether, very interesting :)


    Here, with input buffering, a move is executed and at a certain frame or couple of frames in that move one could input the next move and so on. The move completes and performs the next move afterwards. Like time windows for move execution when a previous move is executed.

    My question would be, instead of interrupting an animation (for a quick looking combo), how would one use the input buffer so that moves are linked and they complete their animations? I am uncertain about pressing a button and waiting for the move to execute.
    I suppose I could have a true/false variable that executes code when the previous move has been executed :)
  • I made a basic prototype for input buffering:

    I have a obj_combo that keeps track of my combo input and removes the input over a certain amount of time.
    Here is my code for obj_test_player's Step Event:
    if qkey{
        obj_combo.keys += "Q";
    }
    if wkey_pressed{
        obj_combo.keys += "W";
    }
    if obj_combo.last_two = obj_combo.combo_1{
        instance_create(x+50,y-90,obj_combo_1);
    }
    if instance_exists(obj_combo_1){
       if obj_combo.last_two = obj_combo.combo_2{
       combo_two = true; 
    } 
    }else{
        if combo_two = true{
            instance_create(x+50,y-140,obj_combo_2);
            combo_two = false;
    }
    }


    Then, in the obj_test_enemy's Step Event:
    if !place_meeting(x,y+1,obj_wall){
        vspd += grav;
    }else{
        if place_meeting(x,y,obj_combo_1){
            hurt_1 = true;
        }
        if hurt_1 = true{
        vspd = -30;
        hurt_1 = false;
        }
        if place_meeting(x,y,obj_combo_2){
            hurt_2 = true;
        }
        if hurt_2 = true{
            vspd = -30;
            hurt_2 = false;
        }
        
    }


    I'm not sure if there is a better way, the first combo executes and straight after the second combo, if input whilst the first combo still exists and the combo's only affect the enemy once, there is no remainder of damage taken whilst colliding with the combo sprite.
  • My question would be, instead of interrupting an animation (for a quick looking combo), how would one use the input buffer so that moves are linked and they complete their animations? I am uncertain about pressing a button and waiting for the move to execute.
    I suppose I could have a true/false variable that executes code when the previous move has been executed :)
    You're already close here. I think you could do this on of two ways (obviously a million+1)

    1.) If during a move the correct button is pressed for the following move (anywhere during the animation) you set a flag so that the current move knows it should cancel into that move at the end of it's animation.

    2.) Assuming all moves return to some neutral state, you could also check if the correct button was pressed not just on the current frame, but say 6 frames back (which is what the input recording is for). So for eg.
    - Current Move = 30 frames
    - Input Buffer = 6 frames
    - You press the correct button on frame 27 of the current move
    So when the Current Move finishes, and returns to your neutral state, you will check up to 6 frames back to see if a valid input was made. So 30-27 = 3, which means the next move will execute.

    1 is more casual friendly since it makes inputs easier. Common in action platformers or action rpgs.
    2 favours precise timing in order to link moves together, which can feel very rewarding for the player once mastered. More commonly used in fighting games and brawlers.

    I use two equal sized lists for calculating when inputs were made,
    input_button[| i];
    input_decay[| i];
    Input_decay stores an initial value, say 120 (=2sec*60fps), that gets decreased by one each frame. At 0 I delete the input_decay[| i] entry and it's corresponding input_button[| i] entry. So to find out how long ago a button was pressed I just calculate 120-input_decay[| i].
    Thanked by 1Jurgen
  • As practice and planning for a prototype fighting game I made this:
    image

    The idea is that one executes a combo that starts some sort of flow for a longer technique. I guess there could be a bar that decreases and afterwards a 'mode' exits.
    Setup+execution.gif
    1754 x 588 - 166K
  • Found this great article on hitboxes in GameMaker.

    Gamemaker basics hitboxes and hurtboxes
Sign In or Register to comment.