I'm not familiar with GM, so forgive me if this is completely off the mark: let me make two assumptions about this code:
1. This snippet is run on every frame (i.e. in the game loop)
2. GameMaker reacts immediately to sprite_index being changed (by immediately changing the sprite)
With that in mind, I suspect your move code is affecting your attack code. Each time this script runs (presumably on every frame), sprite_index is reassigned to one of your other sprites in the move code:
if place_meeting(x,y+1,obj_wall) { ... sprite_index = spr_run_player ... else sprite_index = spr_test_player } else { ... sprite_index = spr_player_jump; else sprite_index = spr_player_fall ... }
So in the frame after you first pressed X, sprite_index will begin as spr_player_swing, but there is no scenario where sprite_index emerges from your move code as spr_player_swing (i.e. it's always changed). I assume GM reacts to this by changing the sprite and reseting spr_player_swing's image_index (what frame of the animation its on).
Then, in your attack code, you set sprite_index to spr_player_swing (if X is pressed), but the image_index has been reset! This causes only the first frame of its animation to ever be visible.
To fix this, try restructuring this code into one if/elseif/else tree. This is just a rearrangement, so no other edits are needed (although, judging from other people's code I've been perusing, you don't need sprite_index != spr_player_swing. I suspect GM doesn't react if you set sprite_index to whatever sprite it's already set to).
if place_meeting(x,y+1,obj_wall) { if (move!=0) ... }</span> else if keyboard_check(ord('X')) { sprite_index = spr_player_swing ... } else { if (vsp < 0) sprite_index = spr_player_jump; else sprite_index = spr_player_fall ... }
A lot of hunches at play here. Let me know if that helps!