Diagonal movement on a grid

D

denpa

Guest
I just started with game maker today and I was wondering how I would go about coding diagonal movement while snapped to a grid. I'm going for movement like in the Mystery Dungeon games. Right now I can move in all directions while snapped, but my diagonal movement code doesn't work and I feel like it has to do with the way I'm handling multiple inputs.

Code:
//Movement
if (place_snapped(32,32)){
    if (keyboard_check(vk_left)){
        motion_set(180,4);
        sprite_index = spr_playerW;
    }
    if (keyboard_check(vk_right)){
        motion_set(0,4);
        sprite_index = spr_playerE;
    }
    if (keyboard_check(vk_up)){
        motion_set(90,4);
        sprite_index = spr_playerN;
    }
    if (keyboard_check(vk_down)){
        motion_set(270,4);
        sprite_index = spr_playerS;
    }
    if (keyboard_check(vk_right) && keyboard_check(vk_up)){
        motion_set(45,4);
        sprite_index = spr_playerNE;
    }
    if (keyboard_check(vk_left) && keyboard_check(vk_up)){
        motion_set(135,4);
        sprite_index = spr_playerNW;
    }
    if (keyboard_check(vk_right) && keyboard_check(vk_down)){
        motion_set(315,4);
        sprite_index = spr_playerSE;
    }
    if (keyboard_check(vk_left) && keyboard_check(vk_down)){
        motion_set(225,4);
        sprite_index = spr_playerSW;
    }
    if (keyboard_check(vk_nokey)){
        motion_set(0,0,);
        if (keyboard_check_released(vk_left)){
            image_index = 0;
        }
        if (keyboard_check_released(vk_right)){
            image_index = 0;
        }
        if (keyboard_check_released(vk_up)){
            image_index = 0;
        }
        if (keyboard_check_released(vk_down)){
            image_index = 0;
        }
        if (keyboard_check(vk_right) && keyboard_check(vk_up)){
            image_index = 0;
        }
        if (keyboard_check(vk_left) && keyboard_check(vk_up)){
            image_index = 0;
        }
        if (keyboard_check(vk_right) && keyboard_check(vk_down)){
            image_index = 0;
        }
        if (keyboard_check(vk_left) && keyboard_check(vk_down)){
            image_index = 0;
        }
    }
}
What happens is that when I move diagonally it won't stop. It keeps moving that way forever.
 

Yambam

Member
You need to modify the diagonal speed slightly so that it snaps at 32x32 points:

PHP:
//Movement
if (place_snapped(32,32)){
    if (keyboard_check(vk_left)){
        motion_set(180,4);
        sprite_index = spr_playerW;
    }
    if (keyboard_check(vk_right)){
        motion_set(0,4);
        sprite_index = spr_playerE;
    }
    if (keyboard_check(vk_up)){
        motion_set(90,4);
        sprite_index = spr_playerN;
    }
    if (keyboard_check(vk_down)){
        motion_set(270,4);
        sprite_index = spr_playerS;
    }
    if (keyboard_check(vk_right) && keyboard_check(vk_up)){
        motion_set(45,4.1140758);
        sprite_index = spr_playerNE;
    }
    if (keyboard_check(vk_left) && keyboard_check(vk_up)){
        motion_set(135,4.1140758);
        sprite_index = spr_playerNW;
    }
    if (keyboard_check(vk_right) && keyboard_check(vk_down)){
        motion_set(315,4.1140758);
        sprite_index = spr_playerSE;
    }
    if (keyboard_check(vk_left) && keyboard_check(vk_down)){
        motion_set(225,4.1140758);
        sprite_index = spr_playerSW;
    }
    if (keyboard_check(vk_nokey)){
        motion_set(0,0);
        move_snap(32,32);
        if (keyboard_check_released(vk_left)){
            image_index = 0;
        }
        if (keyboard_check_released(vk_right)){
            image_index = 0;
        }
        if (keyboard_check_released(vk_up)){
            image_index = 0;
        }
        if (keyboard_check_released(vk_down)){
            image_index = 0;
        }
        if (keyboard_check(vk_right) && keyboard_check(vk_up)){
            image_index = 0;
        }
        if (keyboard_check(vk_left) && keyboard_check(vk_up)){
            image_index = 0;
        }
        if (keyboard_check(vk_right) && keyboard_check(vk_down)){
            image_index = 0;
        }
        if (keyboard_check(vk_left) && keyboard_check(vk_down)){
            image_index = 0;
        }
    }
}
For this I used 32*sqrt(2)=45.254833. Then dividing that by the original speed (4) I get 11,3137. And finally I divide the same number (45.254833) by 11 round I get a number that snaps to 45.254833 (which is the diagonal of a 32x32 square) after 11 steps: 4.1140758.

I added move_snap(32,32) to be sure that it really snaps into place each time, but most of the time it seems to work without too.
 
D

denpa

Guest
Wow how would you even think of that? I don't really understand. It works perfectly though. Thank you.

Edit: Actually I just found a bug that I'm not sure how to fix. If I hold down a diagonal direction for a few seconds, the object will keep moving in that direction without stopping even when I released my keys. I'm not sure what's causing it.
 
Last edited by a moderator:

Yambam

Member
Replace if place_snapped(32,32) with this:

Code:
if abs(x-round(x/32)*32)<=.5&&abs(y-round(y/32)*32)<=.5
And then move move_snap(32,32) directly under this if statement (outside if keyboard_check(vk_nokey)).
 
S

Snail Man

Guest
Let me just say, while Yambam's code does work, it's probably best not to leave that horrible number just floating I your code, probably better to at least store it in a constant. (In case you were wondering, the number was derived from simple Pythagorean geometry a^2 + b^2 = c^2)
 
Top