GM:S 1.4 Diagonal Movement (8 Way)

Discussion in 'Programming' started by Frisk2401, Jul 12, 2019.

  1. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    I would like to be able to make diagonal movement. Here is my code so far.
    Event Left Key:
    if global.canmove=true
    {
    direction=180
    sprite_index=spr_chara_left
    speed=5
    if(keyboard_check_pressed(vk_left)){
    {hspeed=-p_speed}
    }
    }


    Event Up Key:
    if global.canmove=true
    {
    direction=90
    sprite_index=spr_chara_up
    speed=5
    if(keyboard_check_pressed(vk_up)){
    {vspeed=-p_speed}
    }
    }


    Event Right Key:
    if global.canmove=true
    {
    direction=0
    sprite_index=spr_chara_right
    speed=5
    if(keyboard_check_pressed(vk_right)){
    {hspeed=p_speed}
    }
    }


    Event Down Key:
    if global.canmove=true
    {
    direction=270
    sprite_index=spr_chara_down
    speed=5
    if(keyboard_check_pressed(vk_down)){
    {vspeed=p_speed}
    }
    }
     
    Last edited: Jul 13, 2019 at 4:04 PM
  2. Lonewolff

    Lonewolff Member

    Joined:
    Jan 8, 2018
    Posts:
    1,088
  3. JON213

    JON213 Member

    Joined:
    Apr 8, 2019
    Posts:
    14
    This should give you 8 directional movement
    Create
    Xsp=0
    Ysp=0
    Movespeed=5
    Step
    Var vinput = keyboard_check(vk_down)-keyboard_check(vk_up)
    Var hinput = keyboard_check(vk_right)-keyboard_check(vk_left)
    Ysp=vinput*movespeed
    Xsp=hinput*movespeed
    X+=xsp
    Y+=ysp
     
  4. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    Bear with me for a moment, but do you understand your code? Because you are already very close to having eight-way movement implemented, but a single issue in your code stops you in your tracks. Considering a single event, let's say Left Key, it's only 6 effective lines of code, do you know what each one of them does? If you don't, can you provide your most educated guess? Because if you think about it for a bit you should be able to arrive to it. If not, we can get to it together.

    While this code works, in a vacuum, it completely ignores the current implementation (which is based on built-in speed variables and key events) and as such it's not really that advisable.
     
    Nocturne likes this.
  5. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    good job helping 10/10 bro. read the top part.
     
    Last edited: Jul 13, 2019 at 4:04 PM
  6. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    Yes, I do know what it does. I'm just not too good at maths and such, so it's hard for me to do the * and /... I'll keep trying
     
  7. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    The problem is not with the maths, so rest easy on that, the issue is rather in the order (and nature) of instructions, which is why I encourage you to consider the code line by line.
     
  8. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    Alright.. It's just I've been trying to do this for a while and I'm quite new to this whole gamemaker language.. it's been getting on my nerves that I can't figure it out. Which is why'd I'd appreciate help..
     
  9. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    Alright, I suggest you try to figure it out by yourself one last time with one hint: in each event you set the speed twice. Ask yourself why and if it is necessary. If you still can't figure it out I'll explain it to you in long form. Figuring things out by yourself usually is better for learning, but sometimes they are out of one's grasp and that's ok, that's why we inventend the internet.
     
  10. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    Oh, I actually didn't realize I did that! When I remove one of them it only works when I tap it- Wait.. Am I using the wrong check? Edit: Yep.. I was
     
  11. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    4,164
    The code on this topic has basically the same problem as the code from this other topic. Each of these input actions completely negates the effect of all others without ever letting them combine, and that's a common rookie problem. The code should be replaced with an alternative that allows input to be combined, such as this:

    Step:
    Code:
    var dx = keyboard_check(vk_right)-keyboard_check(vk_left);
    var dy = keyboard_check(vk_down)-keyboard_check(vk_up);
    if (dx != 0 || dy != 0) {
      direction = point_direction(0, 0, dx, dy);
      speed = 5;
    } else {
      speed = 0;
    }
    
    The next time you do 8-directional movement or anything else where multiple influences cross-interact, do not code it in a way where a single influence can completely override all others. Let them cross-interact first, then operate on the net result.
     
  12. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    well, thank you for the help, but i'd rather work it out step by step, i didn't really learn anything from that-
     
  13. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    taking from what frostycat said, I need to make the movement code all in the same thing?
     
  14. Annoyed Grunt

    Annoyed Grunt Member

    Joined:
    Jun 20, 2016
    Posts:
    110
    [​IMG]

    GM offers two ways of handling the speed of an instance: either a combination of speed + direction, or horizontal speed + vertical speed. Setting the hspeed or vspeed changes speed and direction, and viceversa.
    Basically, you can either tell the instance "move *speed* amount of units in a specific *direction*", or "move first *hspeed* units horizontally and then *vspeed* units vertically".
    The first error in your code is that you first set the speed and direction and then you set the singular axes. You either do one or the other.
    The second error is that there is no reason to check for keypresses in a key event, the event itself is the check! It only happens if they key is held down.

    Now what you could do is get rid of the speed+direction and only use hspeed and vspeed. Since you can set the axes independently, this will automatically give you 8-way movement, because as you can see from the image above hspeed and vspeed combine to form the "speed" in a 45° angle is they are the same length.

    However this would create yet another problem! You would move faster when you go diagonally. This is because of maths but you can see it clearly from the image itself: the red diagonal arrow that is the sum of the blue arrows is longer than the blue arrows.

    The way frostycat uses is best because he calculates the direction considering both your horizontal and vertical keypresses (currently your keypresses override each other, so only one "wins" in the end) and still allows for 8-way movement.

    You could implement 8-way movement without putting everything into the step event but the way frostycat uses is considerably simpler and more efficient.
     
    Nocturne likes this.
  15. FrostyCat

    FrostyCat Member

    Joined:
    Jun 26, 2016
    Posts:
    4,164
    You learned nothing exactly because you didn't work it out step by step.

    For example, consider what would happen on the line var dx = keyboard_check(vk_right)-keyboard_check(vk_left); in these 4 cases:
    • Neither left nor right key
    • Left key only
    • Right key only
    • Left and right key
    Recall that keyboard_check() would return 1 when the key is held down and 0 when the key is not. dx would get a value of -1, 0 or 1. A similar effect happens on the line after. And once you look up what point_direction() does, you should understand all there is to know about the code I posted.

    By the way, the code I posted has been more or less a standard solution for more than a decade. Part of learning how to code is knowing what the stock solutions are and when and how to apply them. Reinventing the wheel isn't a good way to show your expertise, getting stuff to work is.

    If you insist on using speed and not being 40% something faster when moving diagonally, the best way is to combine the inputs in the Step event. But if you remove that constraint, it's trivial to see how you can keep the keys in separate events.

    As an example, here's what you would have gotten off a pre-YouTube era tutorial on 8-directional movement:

    Left key:
    Code:
    x -= 5;
    Right key:
    Code:
    x += 5;
    Up key:
    Code:
    y -= 5;
    Down key:
    Code:
    y += 5;
    Notice that all of these operate as relative influences on the current position, not absolute authorities on the direction. The principle of operating on net results over absolute cases still holds.
     
    rIKmAN likes this.
  16. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    I know I should be using some stock solutions, I just felt like I'd learn more if I figured out my own way. I understand how stupid that sounds now.
     
  17. Frisk2401

    Frisk2401 Member

    Joined:
    Jul 11, 2019
    Posts:
    35
    I implemented it, but yet now there's a bug but I fixed that. Also, I'm sorry if I come off as rude...
     
    Last edited: Jul 13, 2019 at 5:16 PM
  18. Nocturne

    Nocturne Friendly Tyrant Forum Staff Admin

    Joined:
    Apr 13, 2016
    Posts:
    6,735
    You haven't, so don't worry about it. ;)
     

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