Advertisement
Ulabael

path finding

Oct 10th, 2022 (edited)
928
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /// @description
  2.  
  3. var unitPathExists = false;
  4. var playerPathExists = true;
  5. var player = instance_find(objPlayer, instance_number(objPlayer)-1);
  6. if instance_exists(objUnit) {
  7.     with (objUnit) {
  8.         if path_exists(gridPath) unitPathExists = true;
  9.     }
  10. }
  11.    
  12. // Если все юниты походили - проверяем, есть ли путь у игрока. Если да, то двигаем его.
  13. if !(unitPathExists) {
  14.     // Если игрок есть и у него активен путь
  15.     if player != noone {
  16.         // Если нужно двигаться и путь рассчитан (и активного пути нет) - двигаемся к первой точке пути
  17.         if player.pathActive = true and array_length(player.path) > 0 {
  18.             with (player) {
  19.                 if !path_exists(gridPath) {
  20.                     var start = scr_move_to_point(path[0], global.grid);
  21.                 }
  22.             }
  23.         }
  24.        
  25.         with (player) {
  26.             if (!path_exists(gridPath) and keyboard_check(vk_space)) playerPathExists = false;
  27.             if playerPathExists {
  28.                 // Если игрок находится в финальной точке пути - путь удаляется и возвращается true
  29.                 if scr_unit_at_point(x, y) {
  30.                     event_user(0); // Обновление видимости
  31.                     playerPathExists = false;
  32.                     array_delete(path, 0, 1);
  33.                     if array_length(path) == 0 {
  34.                         pathActive = false;
  35.                     }
  36.                     else {
  37.                         path = scr_find_path([x div CELL_WIDTH, y div CELL_HEIGHT], path[array_length(path)-1], global.grid,, visLines);   
  38.                     }
  39.                     event_user(1); // Обновление отрисовки пути
  40.                 }  
  41.             }
  42.         }
  43.     }
  44. }
  45.  
  46. // Теперь двигаем других микрочелов :)
  47. if instance_exists(objUnit) and !playerPathExists {
  48.     with objUnit {
  49.         event_user(0);
  50.     }
  51. }
  52.  
  53.  
  54. // Стартуем путь до точки. True - если путь начали, false - если нет.
  55. function scr_move_to_point(point, grid){
  56.     var cell = scr_cell_coords(point, grid);
  57.     var _x = cell[0] * CELL_WIDTH;
  58.     var _y = cell[1] * CELL_HEIGHT;
  59.    
  60.     if !(path_exists(gridPath)) {
  61.         gridPath = path_add();
  62.         path_set_closed(gridPath, false);
  63.         path_add_point(gridPath, x, y, 1);
  64.         path_add_point(gridPath, _x, _y, 1);
  65.         path_start(gridPath, 320, path_action_stop, false);
  66.     }
  67. }
  68.  
  69. // Удаляем путь, если дошли до точки
  70. function scr_unit_at_point(_x, _y) {
  71.     if !path_exists(gridPath) return false
  72.     if path_get_x(gridPath, 1) == _x and path_get_y(gridPath, 1) == _y {
  73.         path_delete(gridPath); 
  74.         return true
  75.     }
  76.     return false
  77. }
  78.  
  79.  
  80. // objUnit event_user 0
  81. /// @description
  82.  
  83. var ox = x div CELL_WIDTH;
  84. var oy = y div CELL_HEIGHT;
  85. var maxX = ds_grid_width(global.grid);
  86.  
  87. #region Логика ИИ.
  88.  
  89. #region Поиск пути
  90. if (unitType == unitTypes.enemy) {
  91.     var find = noone;
  92.     if instance_exists(objPlayer) {
  93.         find = scr_find_in_array(visLines, [objPlayer.x div CELL_WIDTH, objPlayer.y div CELL_HEIGHT]);
  94.         if (find != noone) target = objPlayer;
  95.     }
  96.    
  97.     var nbs = scr_neighbors([ox, oy], global.grid,,,,,,true );
  98.     if target != noone  {
  99.         if scr_find_in_array(nbs, target.x div CELL_WIDTH + target.y div CELL_HEIGHT * maxX) == noone {
  100.             if find != noone {
  101.                 path = scr_find_path([ox, oy], [target.x div CELL_WIDTH, target.y div CELL_HEIGHT], global.grid, false);   
  102.             }
  103.         }
  104.         else path = [];
  105.     }
  106. }
  107. #endregion
  108.  
  109. #region Движение по пути
  110. if array_length(path) > 0 {
  111.     gridPath = path_add();
  112.     var cell = scr_cell_coords(path[0], global.grid);
  113.     var _x = cell[0] * CELL_WIDTH;
  114.     var _y = cell[1] * CELL_HEIGHT;
  115.     gridPath = path_add();
  116.     path_set_closed(gridPath, false);
  117.     path_add_point(gridPath, x, y, 1);
  118.     path_add_point(gridPath, _x, _y, 1);
  119.     path_start(gridPath, 320, path_action_stop, false);
  120. }
  121. #endregion
  122.  
  123. #endregion
  124.  
  125.  
  126.  
  127. function scr_neighbors(start, grid, CW = CELL_WIDTH, CH = CELL_HEIGHT, getClosed = false, fourSides = false, ignoreBlocks = false, ignoreUnits = false)
  128. {
  129.     var cellx, celly, cells;
  130.     var neighborsAr = array_create(0, 0)
  131.     // start - это порядковый номер графа
  132.     // Следовательно, нам нужно найти и вернуть соседей при условии, что мы можем по ним пройти
  133.     var maxX = ds_grid_width(grid);
  134.     if is_array(start) {
  135.         cellx = start[0];
  136.         celly = start[1];      
  137.     }
  138.     else {
  139.         cellx = start mod maxX;
  140.         celly = start div maxX;
  141.     }
  142.     // Следовательно, нам нужны: [[-1, -1], [0, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [0, 1], [1, 1]]
  143.     if fourSides
  144.         cells = [[cellx-1, celly], [cellx, celly-1], [cellx+1, celly], [cellx, celly+1]]
  145.     else
  146.         cells = [[cellx -1, celly-1], [cellx, celly-1], [cellx+1, celly-1], [cellx-1, celly], [cellx+1, celly], [cellx-1, celly+1], [cellx, celly+1], [cellx+1, celly+1]]
  147.    
  148.     for (var i = 0; i < array_length(cells); ++i)
  149.     {
  150.         if cells[i][0] > -1 and cells[i][0] < room_width div CW
  151.         and cells[i][1] > -1 and cells[i][1] < room_height div CH
  152.         {
  153.             var meetUnit = position_meeting(cells[i][0] * CW, cells[i][1] * CH, objUnit)
  154.             var meetPlayer = position_meeting(cells[i][0] * CW, cells[i][1] * CH, objPlayer)
  155.             var meetStorage = position_meeting(cells[i][0] * CW, cells[i][1] * CH, objStorage)
  156.             var cellInUnitPath = false;
  157.             with (objUnit) {
  158.                 if array_length(path) > 0 and ((cells[i][0] + cells[i][1] * maxX) == path[0]) {
  159.                     cellInUnitPath = true;                 
  160.                 }
  161.             }
  162.             var meetUnit = instance_position(cells[i][0] * CW, cells[i][1] * CH, objUnit)
  163.             // Если нам нужно отслеживать юнитов
  164.             if !ignoreUnits {
  165.                 // Если в клетке есть кто-то из юнитов - игнор
  166.                 if (meetUnit)
  167.                 or (meetPlayer)
  168.                 or (meetStorage)
  169.                 or cellInUnitPath {
  170.                     continue
  171.                 }
  172.             }
  173.            
  174.             // Если отслеживаем закрытые клетки и текущая клетка НЕ закрыта - игнор
  175.             if getClosed {
  176.                 if ds_grid_get(grid, cells[i][0], cells[i][1] != 0)  
  177.                     continue   
  178.             }
  179.             else // Если отслеживаем открытые клетки, а текущая закрыта - игнор
  180.             {
  181.                 if (!ignoreBlocks and ds_grid_get(grid, cells[i][0], cells[i][1]) == 0) {
  182.                     continue   
  183.                 }
  184.             }
  185.             array_push(neighborsAr, cells[i][0] + cells[i][1] * maxX)
  186.         }
  187.     }
  188.     // Возвращаем список доступных соседей
  189.     return neighborsAr
  190. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement