Need help with walking animation

So I'm working on a top-down farming RPG similar to Stardew Valley and I just finished working on the sprite walking animations. There are three walking animations, one walking vertically towards the bottom of the screen, one walking vertically away towards the top of the screen, and another for horizontal movement which is flipped according to whether the sprite is moving in the negative or positive direction across the X axis. For some reason, my code isn't letting my sprite display these three animations.

For example, if I only have the code for the horizontal movement animation, the animation will play fine, but if i try to add the code for vertical animations, neither animation works unless I press two movement keys at once (up and right arrows, down and left arrows, etc.). I watched I bunch of tutorials and messed around with the code myself, but I can't seem to get the animation working. Here's my code below. If anyone could help, I'd really appreciate it!

key_left = keyboard_check(vk_left);
key_right = keyboard_check(vk_right);
key_up = keyboard_check(vk_up);
key_down = keyboard_check(vk_down);
key_interact = keyboard_check_pressed(vk_space);
var movex = (key_right - key_left)*spd;
var movey = (key_down - key_up)*spd;
hsp = movex * spd;
vsp = movey * spd;
if (place_meeting(x+hsp,y,ocollision)){
while !(place_meeting(x+sign(hsp),y,ocollision)){
x = x + sign(hsp);
hsp = 0;
x = x + hsp;
if (place_meeting(x,y+vsp,ocollision)){
while !(place_meeting(x,y+sign(vsp),ocollision)){
y = y + sign(vsp);
vsp = 0;
y = y + vsp;
image_speed = 1;
if (vsp == 0){
sprite_index = player;
else if (vsp > 0){
sprite_index = playerwf;
else {
sprite_index = playerwb;}
if (hsp == 0){
sprite_index = player;
else {
sprite_index = playerw;
if (hsp != 0){
image_xscale = sign(hsp);


You have to consider vertical and horizontal component at the same time. I would also use a state machine, but you can work without too. Some might do it differently, but this is how I generally do these. First, define a variable facing in Create and set it to zero, which will mean character initially faces to the right. You have eight potential movement directions to consider, and you can get current one by doing, before collision checks:
facing = round(point_direction(0, 0, hsp, vsp) / 45);
Now your facing is an integer from 0 to 7, indicating a direction starting from the right and moving counterclockwise. You also need to know if player is idle or moving. If abs(vsp) + abs(hsp) equals zero, player is idle, otherwise moving. Combining these you can do a selection that picks the correct sprite. I have defined arrays in Create to store that information and just pick from an entry that aligns with facing.

(I also process diagonals more so character always switches facing when entering diagonal direction, so there's actually just four directions defined, but that's beyond just basic movement code).