GM:S 1.4 How to normalize diagonal movement without vector?

Discussion in 'Programming' started by rodrick160, Jun 28, 2016.

  1. rodrick160

    rodrick160 Guest

    Im using a script that essentially checks whether there is a wall in the direction your about to move in, and if not, moves you there. I'm not looking for anything fancy, just a simple formula using hspeed and vspeed and maybe some other variables that will set it to move the same speed diagonally as it does horizontally and vertically. Thanks!

    My movement script:
    Code:
    ///Move Up
    if !(collision_rectangle(x+1,y-var_speed,x+31,y,obj_wall,false,true))
        vspeed=var_speed*-1
    else
        vspeed=0
     
  2. flyingsaucerinvasion

    flyingsaucerinvasion Member

    Joined:
    Jun 20, 2016
    Posts:
    2,168
    not totally sure what your question is but hspeed and vspeed can be normalized by dividing by speed. you'll need to use a temporary variable, because if you do hspeed /= speed, it will change the value of speed at the same time, and then vspeed will have a wrong value.

    var _speed = speed;
    hspeed /= _speed;
    vspeed /= _speed;

    However, if you are using 8-directional movement. You can stop extra diagonal speed like this:
    if (speed > max_speed) { speed = max_speed; }
     
  3. Surgeon_

    Surgeon_ Symbian Curator

    Joined:
    Jun 22, 2016
    Posts:
    248
    You can think of it like this:
    You have two variables, var_speed and direction.
    You can represent that movement with trigonometric functions like this:
    hspeed=+var_speed*cos(direction), and
    vspeed=-var_speed*sin(direction) //Minus here because in Game Maker the Y axis is inverted.
    Since sin(a)^2+cos(a)^2=1, the total speed will always be equal to var_speed.

    With that said, if you just want simple 45-degree diagonal movement, you just need to set
    vspeed=+/-var_speed/sqrt(2), and
    hspeed=+/-var_speed/sqrt(2).

    If you don't know trigonometry, I suggest you learn it. I know it's been an irreplaceable tool for me ever since I've learned it in school.

    -Surgeon_
     
  4. rodrick160

    rodrick160 Guest

    Im assuming 2 is because of pythagoras and assuming var_speed is 1, right? If it were 4 it would be different?
     
  5. hippyman

    hippyman Member

    Joined:
    Jun 20, 2016
    Posts:
    565
    I've done some pretty extensive testing with this specific issue and I've learned that the magic constant is 0.707

    My solution is usually this

    Code:
    Create Event:
    baseSpeed = 4;
    xspeed = 0;
    yspeed = 0;
    
    Step Event:
    var h,v,diag,moveSpd;
    h = key_to_axis(vk_right,vk_left);
    v = key_to_axis(vk_down,vk_up);
    diag = h != 0 && v != 0;
    
    moveSpd = baseSpd;
    if (diag) moveSpd *= 0.707;//if moving diagonally multiply the move speed by the "magical constant"
    
    xspeed = h * moveSpd;
    yspeed = v * moveSpd;
    
    //Collision code here
    
    x += xspeed;
    y += yspeed;
    

    Here's that key_to_axis script
    Code:
    ///key_to_axis(positive,negative);
    return keyboard_check(argument0) - keyboard_check(argument1);
    
     
  6. Surgeon_

    Surgeon_ Symbian Curator

    Joined:
    Jun 22, 2016
    Posts:
    248
    Here's an illustration:

    [​IMG]

    As you can see (because of Pythagoras' theorem), for 45-degree diagonal movement hspeed and vspeed will both always be the maximum speed (var_speed in your case) over square root of 2, then multiplied by +1 or -1, based on direction.

    You can also use Game Maker's built in "speed" and "direction" variables and all of this Game Maker will work out behind the scenes.

    @hippyman 1/sqrt(2)=sin(45)=cos(45)=0.707106781 so your "magic constant" fits with my more mathematical explanation.

    -Surgeon_
     
    hippyman likes this.
  7. hippyman

    hippyman Member

    Joined:
    Jun 20, 2016
    Posts:
    565
    @Surgeon_ That would explain why it works so well! :D Thanks for actually helping me understand how lol
     
  8. Surgeon_

    Surgeon_ Symbian Curator

    Joined:
    Jun 22, 2016
    Posts:
    248
    @hippyman Well, you learn something new every day :D
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice