Windows My Attack Animation appears for a split second

I've set up a simple sprite animation for the attack, i inserted some code and then it works but there's 1 problem, when i press the attack button, the animation appears for a split second and then changes into the idle animation, if i press the button again the same thing happens. What should i do?

(here's my character's step event

key_right = keyboard_check(ord("D"));
key_left = -keyboard_check(ord("A"));
key_jump = keyboard_check_pressed(vk_space);
key_down = keyboard_check(ord("S"));
key_attack = keyboard_check(ord("F"));



move = key_left + key_right;
hsp = move * movespeed;
if (vsp < 10) vsp += grav;

if (place_meeting(x,y+1,obj_parede))
{
if (key_jump) vsp = key_jump * -jumpspeed;
}




if (place_meeting(x+hsp,y,obj_parede))
{
while(!place_meeting(x+sign(hsp),y,obj_parede))
{
x += sign(hsp);
}
hsp = 0;
}
x += hsp;

if (place_meeting(x,y+vsp,obj_parede))
{
while(!place_meeting(x,y+sign(vsp),obj_parede))
{
y += sign(vsp);
}
vsp = 0;
}


y += vsp;


if (move!=0) image_xscale = move;
if (place_meeting(x,y+1,obj_parede))
{
if (move!=0) sprite_index = spr_bagulhowalk; else sprite_index = spr_bagulho;
}
else
{
if (vsp < 0) sprite_index = spr_bagulhojump; else sprite_index = spr_bagulhofall;
}

if keyboard_check_pressed (ord("F"))
{
if (place_meeting(x, y, obj_parede)) sprite_index = spr_bagulho else sprite_index = spr_bagulhoattack
}
(parede is wall in portuguese))
 

jaredk_

Member
The reason the animation is only playing for one frame is because you have this portion:


if (place_meeting(x,y+1,obj_parede))
{
if (move!=0) sprite_index = spr_bagulhowalk; else sprite_index = spr_bagulho;
}
else
{
if (vsp < 0) sprite_index = spr_bagulhojump; else sprite_index = spr_bagulhofall;
}

Running at all times before your condition which triggers the attack animation here:


if keyboard_check_pressed (ord("F"))
{
if (place_meeting(x, y, obj_parede)) sprite_index = spr_bagulho else sprite_index = spr_bagulhoattack
}

"keyboard_check_pressed" only triggers for one frame, the moment it detects that the key was pressed. Essentially what your code is doing is setting the dudes animation to the attack, but then immediately overriding it back to the previous animation with that portion of code that's happening above. To fix this, the best way would be to set up some sort of animation state system. I.e., the character needs a way of tracking which animation it is currently playing, as to not allow animation switches at unwanted times or other unintended behavior.
 
The reason the animation is only playing for one frame is because you have this portion:


if (place_meeting(x,y+1,obj_parede))
{
if (move!=0) sprite_index = spr_bagulhowalk; else sprite_index = spr_bagulho;
}
else
{
if (vsp < 0) sprite_index = spr_bagulhojump; else sprite_index = spr_bagulhofall;
}

Running at all times before your condition which triggers the attack animation here:


if keyboard_check_pressed (ord("F"))
{
if (place_meeting(x, y, obj_parede)) sprite_index = spr_bagulho else sprite_index = spr_bagulhoattack
}

"keyboard_check_pressed" only triggers for one frame, the moment it detects that the key was pressed. Essentially what your code is doing is setting the dudes animation to the attack, but then immediately overriding it back to the previous animation with that portion of code that's happening above. To fix this, the best way would be to set up some sort of animation state system. I.e., the character needs a way of tracking which animation it is currently playing, as to not allow animation switches at unwanted times or other unintended behavior.
i have absolutely no idea how to do that but thanks anyways for the advice. I think i'm gonna need someone to fix this problem for me via the comments, but thanks anyways dude, good luck with the corona virus!
 

ophelius

Member
He's saying you should always only check for input once per frame and store it in a variable. Don't use any of the keyboard_check functions more than once for each action in the step. You did that at the top for the F key, so just use

if(key_attack)
{
if (place_meeting(x, y, obj_parede)) sprite_index = spr_bagulho else sprite_index = spr_bagulhoattack
}

I don't know if that solves the problem but it's a start in the right direction
 
Last edited:

Imperial

Member
You need to use something like a State Design Pattern

GML:
if(place_meeting(x,y+1,obj_parede))
{
    if(keyboard_check(ord("F")))
    {
        sprite_index = spr_bagulhoattack;
    }
    else
    {
        if(move != 0)
        {
            sprite_index = spr_bagulhowalk;
        }
        else
        {
            sprite_index = spr_bagulho;
        }
    }
}
 
He's saying you should always only check for input once per frame and store it in a variable. Don't use any of the keyboard_check functions more than once for each action in the step. You did that at the top for the F key, so just use

if(key_attack)
{
if (place_meeting(x, y, obj_parede)) sprite_index = spr_bagulho else sprite_index = spr_bagulhoattack
}

I don't know if that solves the problem but it's a start in the right direction
Thanks! It worked...to a certain degree
see, now the animation plays like it should, it works better than i expected actually but there's one problem, i need to hold the attack button to play the full animation, and the attack animation overrides other animations, i think this can be solved with a timer but i don't know how to do it, but thanks anyways!
 
You need to use something like a State Design Pattern

GML:
if(place_meeting(x,y+1,obj_parede))
{
    if(keyboard_check(ord("F")))
    {
        sprite_index = spr_bagulhoattack;
    }
    else
    {
        if(move != 0)
        {
            sprite_index = spr_bagulhowalk;
        }
        else
        {
            sprite_index = spr_bagulho;
        }
    }
}
Thanks it worked! the attack animation no longer overrides the normal animations, but i still need to hold the attack button, but that's dealable! Thanks a lot!
 
Top