1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

Pac-Man Movements

Discussion in 'Programming' started by Qing Donnie Yoshi, Oct 26, 2019.

  1. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    I think I'm using the test object
     
  2. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK so turns out i didn't have the GUI in neither Pac or the test but as an object of it's own so that was a derp moment. As for the proper use for it, it says that the numbers on the right does change but it changes right back to be identical to the numbers on the left. So in a way it is saving the key press but only for a split second.
     
  3. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Well, I guess you could try replacing
    Code:
    new_dir = direction;
    with empty brackets:
    { }

    Worst case, it should give the player an unlimited amount of time to change direction.
     
  4. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    The whole code? or put it between the brackets?
     
  5. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK I replaced it with the brackets but now he can't move up or down.
     
  6. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    *edit* Ignore this post now.
     
    Last edited: Nov 13, 2019
  7. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Okay, go back to using the normal code, not the one I posted last. Use the one that sets new_dir = direction, since that line of code was correct. What you need to change is all the keyboard_check_pressed() calls into plain old keyboard_check() calls.

    The original code was intended to only make Pac-Man change directions when within a single tile's length away from a junction. That was fine and dandy, except the player has 2/15 of a second to react. lol So what you needed was a margin of error. The simplest way to do that was to let the player hold a direction indefinitely.

    However, there is one significant drawback to this: multiple key presses. In the code here, holding left and up would make Pac-Man only look for an upward path, ignoring any paths to the left. This is because of the else in the code. If you removed the else, then Pac-Man would only look for the leftward path, ignoring any paths up. I mean, in either case that's the player's fault, but it's something to be aware of. That problem would rarely arise using _pressed, but as we've seen it causes other problems of its own.
     
  8. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    the best results I've gotten
     
  9. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK so what I wanna do now is have the AI Pac-Man and I think I have the concept of it but I wanna make sure it eats all available Pac-dots and Power Pellets. Any pointers or ideas?
     
  10. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    An AI for Pac-man? Ooh, that's tricky. If you read my posts about Ghost AI, it would be similar. You pick a target (probably instance_nearest(x,y,Pellet)'s x and y coordinates to find the nearest pellet) and save the coordinates in variables. Then have Pac-Man pick the paths that would get him to the pellets every time he reaches a junction (see the GhostAI posts about that part). But the catch is now you need to also avoid Ghosts, so if the path to the nearest pellet leads to a Ghost, you wouldn't want to take it. So like I said, it's very tricky.
     
    Qing Donnie Yoshi likes this.
  11. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    You mean this line of codes right here?

    Yeah, I've seen some of the old Pacman GM8 games and wasn't a fan of their codes, even before I looked into how Pacman was made. lol

    Ghosts only change direction at intersections, or every 8 pixels (the size of a tile) originally. There is no real collision detection in the ghosts ever, subsequently. Since Neither ghosts nor Pacman can move diagonally, you can tell if they are at an intersection using the conditional
    if !((x + y) mod tile_size)
    Replacing tile_size with the size of your tiles. Or if your tile size is a power of 2 (e.g.,2,4,8,16,32,64), you can also use
    if !(x + y & tile_size)
    The (x+y) part changes if your ghosts aren't aligned to the grid quite right. For example, the original code was if !(((x-4)+(y-4)) mod 8) because ghosts and Pacman were misaligned by 4 pixels.

    Ghosts don't randomly change directions; they have very structured movement patterns. When the ghost reaches a junction (when x+y&7==0), it generates a list of all 4 directions around it. Another rule of ghosts is that they cannot reverse direction, so then the ghost removes the direction behind it from the list (i.e., if the ghost has direction 90, it removes 270 from the list). Then for each direction still in the list, it checks if there is a block in the way and removes that direction from the list if it is blocked. If there is only one direction left, the ghost heads in that direction; otherwise the ghost then picks a target location where it wants to go:

    • Blinky's target location is wherever Pacman is at that time.
      targetX = Pacman.x; targetY = Pacman.y;
      find_best_path();
    • Pinky's target location is 2 or 3 tiles ahead of Pacman.
      targetX = Pacman.x; targetY = Pacman.y;
      switch Pacman.direction {
      case 0: targetX += tile_size * 3; break;
      case 90: targetY -= tile_size * 3; break;
      case 180: targetX -= tile_size * 3; break;
      case 270: targetY += tile_size * 3; break;
      }
      find_best_path();
    • Inky's target location is to a pincer attack in tandem with Blinky.
      targetX = (Pacman.x * 2 - Blinky.x) mod room_width; //this was 256 in the old games
      targetY = (Pacman.y * 2 - Blinky.y) mod room_height; //again, this was 256
      find_best_path();
    • Clyde's target location was a bit more complex. If he was more than 4 tiles away from Pacman, the target location was Pacman's current position, but if he was closer than that, he would change direction; by default, he'd try to run down (I think it was down).
      if abs(Pacman.x - x) < tile_size * 4 && abs(Pacman.y - y) < tile_size * 4 {
      direction = 270;
      find_new_direction();
      }
      else {
      targetX = Pacman.x; targetY = Pacman.y;
      find_best_path();
      }
    • Fruit would try to get to the Ghost House, which obviously it can't get into, so it just moves around the field seemingly randomly.
    The find_best_path() script would just be a script that would figure out which direction the target locations are relative to the ghost and then check if the best-fitting direction is in the list. If it is, it chooses that direction; but if it's not, it checks if the next best-fitting direction is in the list and chooses that. If even that's not available, it picks a random one from the list. This is the only random aspect of a ghost's movement, which usually only happens when the target location is behind the ghost.

    The find_new_direction() script is also a random aspect, but it still follows the same direction picking rules as find_best_path().
     
  12. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    There's that one, and then there is the one I posted in another guy's thread about ghost AI using drag-and-drop.
     
  13. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    what's the DnD version?
     
  14. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    Also does the ghost have the same step movement as pac minus the keyboard_checks?
     
    Last edited: Nov 16, 2019
  15. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    You're still there?
     
  16. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    The DnD post is right below this one. But the op of that post is still having issues. You can giveit a go and see if you have the same issues. Remember to apply what we did here to the ghost's code.
     
  17. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK so they all have the step codes as Pac-Man and the target code for each of them should be included the step?
     
  18. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Yes. I would pick a target pill when aligned to the grid. Although I was thinking instead of finding the nearest pill, i'd first check the adjacent cells for pills firsts.
     
  19. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    And what about these codes: !((x + y), mod tile_size)!(x + y & tile_size), (x+y)
    what do I do with these?
     
  20. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    tile_size is the same as grid in your case
     
  21. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    No I mean like do I put said code in step or in create?
     
  22. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Everything is Step
     
  23. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    This is what I have but I'm not sure how I'm going about it

    Step:
    if direction == (new_dir + 180) mod 360 {
    direction = new_dir;
    speed = 3;
    image_speed = 1;
    switch direction {
    case 0: sprite_index = Blinky_right; break;
    case 90: sprite_index = Blinky_up; break;
    case 180: sprite_index = Blinky_left; break;
    case 270: sprite_index = Blinky_down; break;
    }
    }
    else
    if (x - grid/2) mod grid == 0 && (y-grid/2) mod grid == 0 {
    var h = lengthdir_x(grid/2, new_dir);
    var v = lengthdir_y(grid/2, new_dir);
    if place_meeting(x+h,y+v,obj_Ghost_Collision)
    new_dir = direction;
    else {
    direction = new_dir;
    speed = 4;
    image_speed = 1;
    switch direction {
    case 0: sprite_index = Blinky_right; break;
    case 90: sprite_index = Blinky_up; break;
    case 180: sprite_index = Blinky_left; break;
    case 270: sprite_index = Blinky_down; break;
    }
    }
    }
    {
    if !((x + y) mod grid)
    targetX = obj_Player_1.x; targetY = obj_Player_1.y;
    find_best_path();
    }
    move_wrap(1,1,2);

    create:
    targetX =
    targetY =
    find_best_path =
    new_dir = direction;
    sprite_index = Blinky_left;
    image_speed = 1;
    speed = 3;
    grid = 32;
     
  24. JaimitoEs

    JaimitoEs Member

    Joined:
    Aug 9, 2016
    Posts:
    175
    Edit, i see the new code.... forget my comment...but why are you using directions instead of profit your array/grid to move the player? it´s a bit over complicated but, to be your first game is really good! keep up with code!
     
    Last edited: Nov 19, 2019
  25. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    He's not using a real grid, in this case grid is just the size of the walls.


    for the ghost AI, forget everything you learned in the Pac-Man player controls. The ghosts are a) not Pac-Man, and b) not player-controlled. Youdon't need new_dir for AI. the AI will only change their directions when they are at an intersection. The same is true for the Pac-Man AI, but Pac-Man AI also needs to check every step to make sure he doesn't actually run into a ghost.

    If you look at the AI from the drag-and-drop post, what is going on is the ghost first checks if it is at an intersection, then it fills an array with whether there is a path in each direction, then removes that path from the array if it's the opposite direction the ghost is currently going (doesn't apply to Pac-man AI), then picks which of the available paths is the best one to take.

    The DnD AI post:
    https://forum.yoyogames.com/index.p...y-movement-for-a-maze-game.66768/#post-406035
     
  26. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    Ima be honest, I'm all types of lost in that thread. I don't even know how to interpret the whole whole convo.
     
  27. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Ok, fine. Let's take a look at Blinky, the most basic ghost in Pac-Man. Since he is the most basic ghost, we will also make him the parent of all other ghosts.

    In the Begin Step event, specify the target coordinates to move toward. In Blinky's case, the target coordinates are usually Pac-man's. When Pac-man is invincible, Blinky tries to run toward one of the corners, so we need to specify that. For Pac-Man's invincibility, I will use the global variable global.PillPower. If the ghost is dead, I use the instance variable goHome.
    Code:
    ///Begin Step Event
    if goHome {
        targetX = //whatever the x-coordinate is for the ghost's home;
        targetY = //whatever the y-coordinate is for the ghost's home;
        speed = 4;
    }
    else
    if global.PillPower {
        targetX = 0;
        targetY = 0;
        speed = 4;
    }
    else {
        targetX = obj_Player_1.x;
        targetY = obj_Player_1.y;
        speed = 4;
    }
    
    Note: I set speed like this here instead of the Create Event because technically the ghosts can move at different speeds depending on if they're fleeing or attacking. In your particular case, it likely doesn't matter where you set it.

    Unlike Pac-man, Blinky can only change directions when he's in the middle of a junction -- ghosts cannot go backwards normally. This is actually good for the ghosts, since the player will be unable to trick them into a back-and-forth loop. Like Pac-man, we know Blinky is in the middle of a junction when (x - grid/2) mod grid == 0 && (y-grid/2) mod grid == 0, assuming you centered the origin for Blinky's sprite. But again, unlike Pac-Man, we can't just worry about walls in the direction Blinky wants to move, but all the walls around him so he can hopefully pick the best route toward his target. To do this, we need an array of all available directions excluding the path that is directly behind Blinky -- ghosts cannot go backwards normally.

    After we have the array of viable paths filled out, we need to find the best path toward the target. If there is only one available path, we take that one, otherwise we need to deduce the best available path. To figure that out, we need to find the distance to the target. When moving along a grid, the distance to any point is abs(x1-x2)+abs(y1-y2). In most cases, we don't care about the total distance toward the target, we only need to worry about which distance -- horizontal or vertical -- is more significant. If the vertical distance was greater than the horizontal distance, the ghost would try to move vertically. If that desired path is unavailable, you try the next preferred path. So if Blinky wanted to move down and right but there was a wall below him, he would try to move right. If moving in the other direction is not an option, you randomly pick one of the available options.

    Note: This method is a little different from the one I gave the other guy.

    Code:
    ///Step Event
    if (x - grid/2) mod grid == 0 && (y-grid/2) mod grid == 0 {
        for(var paths, i=0; i<4; i++;)
            paths[i] = -1;
        var n = 0;
        for(i=0; i<360; i+= 90;) {
            if i != (direction + 180) mod 360
            if !place_meeting(x+lengthdir_x(grid/2,i), y+lengthdir_y(grid/2,i), obj_Pac_Collision)
                paths[n++] = i;
        }
        if paths[0] == -1 {  //this should NEVER happen, but just in case...
            direction = 270;
            exit;
        }
        if paths[1] == -1 {  //this means there is only one path available
            direction = paths[0];
            exit;
        }
        var h = abs(targetX - x);
        var v = abs(targetY - y);
        var dx = point_direction(x,y,targetX,y);
        var dy = point_direction(x,y,x,targetY);
        if h > v {
        //Try to move horizontally
            for(i=0; i<4; i++;)
                if paths[i] == dx {
                    direction = dx;
                    exit;
                }
            for(i=0; i<4; i++:)
                if paths[i] == dy {
                    direction = dy;
                    exit;;
                }
        }
        else
        if v > h {
        //Try to move vertically
            for(i=0; i<4; i++;)
                if paths[i] == dy {
                    direction = dy;
                    exit;
                }
            for(i=0; i<4; i++;)
                if paths[i] == dx {
                    direction = dx;
                    exit;
                }
        }
        //If both distances are the same or both desired paths are unavailable, pick a random one
        i = irandom(3);
        while paths[i] == -1
            i = ++i mod 4;
        direction = paths[i];
    }
    Or if you would rather use a ds_list instead of an array, you could try the following.

    Code:
    ///Create Event
    paths = ds_list_create();
    Code:
    ///Step Event
    if (x - grid/2) mod grid == 0 && (y-grid/2) mod grid == 0 {
        ds_list_clear(paths);
        for(i=0; i<360; i+= 90;)
            if i != (direction + 180) mod 360
            && !place_meeting(x+lengthdir_x(grid/2,i), y+lengthdir_y(grid/2,i), obj_Pac_Collision)
                ds_list_add(paths,i);
        if !ds_list_size(paths) {  //this should NEVER happen, but just in case...
            direction = 270;
            exit;
        }
        if ds_list_size(paths) == 1 {  //this means there is only one path available
            direction = paths[|0];
            exit;
        }
        var h = abs(targetX - x);
        var v = abs(targetY - y);
        var dx = point_direction(x,y,targetX,y);
        var dy = point_direction(x,y,x,targetY);
        if h > v {
        //Try to move horizontally
            if ds_list_find_index(paths, dx) > -1 {
                direction = dx;
                exit;
            }
            if ds_list_find_index(paths,dy) > -1 {
                direction = dy;
                exit;
            }
        }
        else
        if v > h {
        //Try to move vertically
            if ds_list_find_index(paths,dy) > -1 {
                direction = dy;
                exit;
            }
            if ds_list_find_index(paths,dx) > -1 {
                direction = dx;
                exit;
            }
        }
        //If both distances are the same or both desired paths are unavailable, pick a random one
        i = irandom(3) * 90;
        while ds_list_find_index(paths,i) < 0
            i = (i + 90) mod 360;
        direction = i;
    }
     
    Last edited: Nov 24, 2019
    IndianaBones likes this.
  28. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    ok other than a few errors what should I do for create?
     
  29. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Nothing, unless an unknown variable error pops up, in which case you need to define that variable.

    Edit: You need to set goHome to false in Create Event.

    Set global.PillPower to false in Pac-man's create event; when Pac-man becomes invincible, set global.PillPower to true and set an alarm to how long you want it to last. Then in the alarm event, set global.PillPower back to false.
     
    Last edited: Nov 25, 2019
  30. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK other than a typo in the code the only thing that needs to be defined is the GoHome variable
     
  31. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Where did i typo? I will fix it. My eyes are too tired to spot it. lol
     
  32. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    Don't worry it was just a simple switch from ":" to ";" in line 30. The problem I'm having rn is figuring out how to refrence goHome more than once. I've tried saying "goHome = (targetX and targetY)" but that didn't work.
     
    Last edited: Nov 26, 2019
  33. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    what you think I should do?
     
  34. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    goHome is just a true-false variable. When Pac-man eats a ghost, you set that ghost's goHome to 1 (true) and change its sprite to the disembodied eyes. The Begin Step event will then see that goHome is true and then update targetX and targetY in that ghost.
     
  35. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    this error says otherwise

    ___________________________________________
    ############################################################################################
    FATAL ERROR in
    action number 1
    of Step Event1
    for object obj_Blinky:
    Variable obj_Blinky.goHome(100007, -2147483648) not set before reading it.
    at gml_Object_obj_Blinky_Step_1 (line 2) - if goHome {
    ############################################################################################
    --------------------------------------------------------------------------------------------
    stack frame is
    gml_Object_obj_Blinky_Step_1 (line 2)
     
  36. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    I told you, you need to set it to 0 (false) in the Create Event.
     
  37. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    Oh my bad I actually missed that part.
     
  38. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK the code works now but it seems he stop when colliding with the wall, let a lone that that he actually look lifeless without the animations.
     
    Last edited: Nov 27, 2019
  39. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    For ghosts, you only need to set the sprite sprite properties in the Create event. You can change the sprite_index when changing directions, but set the image_speed once.

    Are you talking about the ghost stopping or Pacman AI stopping? The ghost should never stop unless you set speed to 0.
     
  40. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK turns out I had to adjust the origin. So as of now Blinky is officially pursuing Pac-Man. now I need to add the animation as well as fix the warping problem because instead of him going from one tunnel to the other he just hang outside the wall view.
     
  41. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Did you use move_wrap(true,true,2) like you did with Pac-Man?

    If I remember right, the ghosts had special exceptions for going through the warp tunnels. Try using move_wrap(true,true,4). If that doesn't work, you may need to set an alarm when the ghost wraps and in that alarm's event just put an empty comment so the alarm counts down without actually doing anything, and then tell the ghost to not try to change directions when the alarm is greater than 0 (but try adjusting move_wrap first).

    Is your ghost moving with speed 4 just like you did with Pac-Man?
     
  42. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    Yes I did use speed 4 for the ghost and the same move_wrap code pac-man has. Also for the alarm even't do I just say "if wrap = !direction"?
     
    Last edited: Nov 28, 2019
  43. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Don't put anything in the alarm if you use an alarm. But first, try just setting the move_wrap to 4 instead of 2.

    OOH! Or when the ghost wraps, increase it manually also.

    x+=hspeed;
    y+=vspeed;

    I think there is an event for when it wraps.
     
  44. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    so turns out I had the wrap code in the wrong place. I had it in create instead of step
     
  45. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OK so all ghost is now the child of Blinky and are following target successfully. I tried to change their sprites so they would look like they're going to said direction but no luck.
     
  46. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    You should make up 4 variables or an array in the Create event of each ghost for each sprite, then reference those variables/array in the Step event instead of actual sprites.

    E.g.:

    sprite_up = Blinky_Up;
    sprite_down = Blinky_Down;
    sprite_right = Blinky_Right;
    sprite_left = Blinky_Left;

    Then in the Step event, reference sprite_up instead of Blinky_Up.
     
  47. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    so in step it'd be something like this?

    {
    direction = 180;
    image_index = sprite_up;
    }
     
  48. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Well, when direction is 180,it'd be sprite_left, but yes.

    By using a set of variables like that, you can define the variables in each ghost's create event, define the target location in each ghost's Begin Step event (if you want them to have different movements), then have just o e Step event between them all. This keeps code much cleaner and easier to manage.
     
  49. Qing Donnie Yoshi

    Qing Donnie Yoshi Member

    Joined:
    Aug 26, 2019
    Posts:
    72
    OMG I ain't realize what I typed until you pointed it out, I'm so sorry lol. OK so this is what result in:

    step

    ///Step Event
    if (x - grid/2) mod grid == 0 && (y-grid/2) mod grid == 0 {
    for(var paths, i=0; i<4; i++;)
    paths = -1;
    var n = 0;
    for(i=0; i<360; i+= 90;) {
    if i != (direction + 180) mod 360
    if !place_meeting(x+lengthdir_x(grid/2,i), y+lengthdir_y(grid/2,i), obj_Pac_Collision)
    paths[n++] = i;
    }
    if paths[0] == -1 { //this should NEVER happen, but just in case...
    direction = 270;
    exit;
    }
    if paths[1] == -1 { //this means there is only one path available
    direction = paths[0];
    exit;
    }
    var h = abs(targetX - x);
    var v = abs(targetY - y);
    var dx = point_direction(x,y,targetX,y);
    var dy = point_direction(x,y,x,targetY);
    if h > v {
    //Try to move horizontally
    for(i=0; i<4; i++;)
    if paths == dx {
    direction = dx;
    exit;
    }
    for(i=0; i<4; i++;)
    if paths == dy {
    direction = dy;
    exit;;
    }
    }
    else
    if v > h {
    //Try to move vertically
    for(i=0; i<4; i++;)
    if paths == dy {
    direction = dy;
    exit;
    }
    for(i=0; i<4; i++;)
    if paths == dx {
    direction = dx;
    exit;
    }
    }
    //If both distances are the same or both desired paths are unavailable, pick a random one
    i = irandom(3);
    while paths == -1
    i = ++i mod 4;
    direction = paths;
    }
    {
    move_wrap(1,1,2);
    }
    {
    direction = 180;
    sprite_index = sprite_left;
    }
    {
    direction = 0;
    sprite_index = sprite_right;
    }
    {
    direction = 90;
    sprite_index = sprite_up;
    }
    {
    direction = 270;
    sprite_index = sprite_down;
    }
     
  50. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,136
    Oh, you need to make those conditionals.
    E.g.:

    switch direction {
    case 0: sprite_index = sprite_right; break
    case 90: sprite_index = sprite_up; break
    case 180: sprite_index = sprite_left; break
    case 270: sprite_index = sprite_down; break
    }
     

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