1. Hey! Guest! The 36th GMC Jam will take place between February 27th, 12:00 UTC - March 2nd, 12:00 UTC. Why not join in! Click here to find out more!
    Dismiss Notice
  2. NOTICE: We will be applying a Xenforo update on Tuesday 25th of February. This means that from approximately 10:00 to 14:00 BST the forums will be offline (or possibly longer). Sorry for the inconvenience! Official Announcement here.

GM:S 1.4 [SOLVED] Animation Plays Random Frame?

Discussion in 'Programming' started by Blaize, Jan 31, 2017.

  1. Blaize

    Blaize Member

    Joined:
    Jul 27, 2016
    Posts:
    63
    Hey all,

    So, I'm branching my code skills a little here and so I have a one button combo mechanic in my game where you just press one key to do a three-hit combo and each stage of the combo is a separate animation. Pretty simple, right? Problem is, occasionally I get this weird thing where it plays only part of the animation (sometimes not at all!), not the whole thing but it still registers input. Here is the demo if you need to try it out for yourself (W-key to play the animations) hopefully you can get the issue.

    Here is the code I'm using:
    Create:
    Code:
    Combo[0]=Combo0; //animations
    Combo[1]=Combo1;
    Combo[2]=Combo2;
    ComboTimer = 0; //when this hits 0, go back to idle animation
    ComboStep = 0; //which stage of the combo we're at
    AttackAgain = true;
    Attacking = false; //playing the animation?
    ChainEnd = false; //at the end of the combo?
    image_speed = 0.2;

    EDIT:
    I'm using keyboard_check_pressed() to check for input if that helps any. I have a feeling that it might be an in-between-frames thing and that is beyond me at this moment.
    Step:
    Code:
    if (_attackKey && !Attacking && (ComboStep < array_length_1d(Combo)))
    {
        ChainEnd = false;
        Attacking = !Attacking; //flip the bool
        AttackAgain = !AttackAgain;
        sprite_index = Combo[ComboStep];
        ComboStep ++;
        ComboTimer = 6;
    }
    Animation End:
    Code:
    if (Attacking)
    {
        Attacking = !Attacking; //flip the bool again
        AttackAgain = !AttackAgain;
        sprite_index = vIdle;
    }
    if (ComboStep >= array_length_1d(Combo)) //since we've hit the end of the combo, we need to reset
    {
        ComboStep = 0;
        sprite_index = vIdle;
    }
    I also have a custom timer (in the end step event) instead of using alarms that cancels the combo if you're too slow.
     
    Last edited: Feb 1, 2017
  2. Kyle Rider

    Kyle Rider Guest

    I had this problem as well. This is when I started getting into using a state engine.
    Code:
    if (!jump && !fall && !vtalk)
    {
        if (key_attack != 0)
        {
            sprite_index = spr_vattack;
            image_index = 0;
            state = states.attack;
        }
    }
    
    and then my state is:
    Code:
    //sprite_index = spr_vattack;
    //image_index = 0;
    image_xscale = dir;
    image_speed = anim_speed;
    if ((image_index >= 1) && (image_index <=4))
    {
        with (instance_create_depth(x,y,-1000,obj_hitbox))
        {
            image_xscale = other.image_xscale;
            with(instance_place(x,y,par_enemy))
            {
                if (hit == 0)
                {
                    hit = 1;
                }
            }
        }
    }
    
    //TAKING DAMAGE!//
    //////////////////
    if vhit = 2
    {
        global.php--;
        if (alarm[0] = -1) alarm = 15;
        image_blend = make_color_hsv(0, 10, 125);
        vhit = 0;   
    }
    
    You have to set up your states before using them. I set them up in the room creation at game_boot. I recommend using Shaun Spaldings state engine tutorial.
     
  3. Blaize

    Blaize Member

    Joined:
    Jul 27, 2016
    Posts:
    63
    Yeah I implemented a state machine after I posted, but I still got the same issue of random frames playing or not at all. Instead of naming states explicitly (seeing as it's really just a part of the attack state) I created a switch statement that relied used the combo counter. Something like this:
    Code:
    ///Hooray pseudo-code!
    if (attack key is pressed)
    {
         switch (combonumber)
         {
               case 0:
               //animate, hitboxes, etc
               break;
               //etc...
          }
          combonumber ++;
    }
     
  4. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,449
    Make sure you are setting the image_index back to 0 every time you change sprites. (except in the Animation End event, as sprite changes there should result in 0; but I could be wrong)
     
  5. Blaize

    Blaize Member

    Joined:
    Jul 27, 2016
    Posts:
    63
    Hit the nail on the head, problem solved!
    So here's what my (pseudo)code looks like now:
    Code:
    if (attack key is pressed)
    {
        switch(combo number){
        case 0:
              switch sprite
              image_index = 0; //big thanks to TheouAegis!
              //Whatever else needs to happen
         break;
         //continue with other cases
         }
         combo number ++;
    }
    And as far as I can tell, Animation End does come up with 0
     

Share This Page