Legacy GM [SOLVED] Animation Plays Random Frame?

B

Blaize

Guest
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 by a moderator:
K

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

Blaize

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.
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 ++;
}
 

TheouAegis

Member
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)
 
B

Blaize

Guest
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)
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
 
Top