Advertisement
equus09

Pathfind

Jul 21st, 2019
288
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.36 KB | None | 0 0
  1. # I made changes to original code. The original code is here:
  2. # https://github.com/GDquest/Godot-engine-tutorial-demos/blob/master/2018/03-30-astar-pathfinding/pathfind_astar.gd
  3. # **MIT License**
  4. #
  5. # Copyright (c) 2017 Nathan Lovato
  6. #
  7. # Permission is hereby granted, free of charge, to any person obtaining a copy
  8. # of this software and associated documentation files (the "Software"), to deal
  9. # in the Software without restriction, including without limitation the rights
  10. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. # copies of the Software, and to permit persons to whom the Software is
  12. # furnished to do so, subject to the following conditions:
  13. #
  14. # The above copyright notice and this permission notice shall be included in all
  15. # copies or substantial portions of the Software.
  16. #
  17. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  20. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  23. # SOFTWARE.
  24. extends Object
  25. class_name SEnemyGridAStarPathfind
  26.  
  27. var astar : AStar setget , get_astar
  28. var _astar : AStar
  29. var _map_size : Vector2
  30. var _point_path : PoolVector3Array = PoolVector3Array()
  31. var _tile_map : TileMap
  32. var _obstacle_cells_id: int
  33. var _half_cell_size : Vector2
  34.  
  35.  
  36. func get_astar() -> AStar:
  37. if _astar == null:
  38. _astar = AStar.new()
  39. return _astar
  40.  
  41.  
  42. func _init(p_tile_map: TileMap, p_obstacle_cells_id: int -> void:
  43. _tile_map = p_tile_map
  44. _map_size = _tile_map.get_used_rect().size
  45. _half_cell_size = _tile_map.cell_size * 0.5
  46. _obstacle_cells_id = p_obstacle_cells_id
  47. set_obstacles(_tile_map.get_used_cells_by_id(_obstacle_cells_id))
  48.  
  49.  
  50. func set_obstacles(p_obstacle_positions: PoolVector2Array) -> void:
  51. var walkable_cells_list : PoolVector2Array = astar_add_walkable_cells(p_obstacle_positions)
  52. astar_connect_walkable_cells(walkable_cells_list)
  53.  
  54.  
  55. # Loops through all cells within the map's bounds and
  56. # adds all points to the _astar, except the obstacles
  57. func astar_add_walkable_cells(p_obstacle_positions: PoolVector2Array) -> PoolVector2Array:
  58. var points_array: PoolVector2Array = PoolVector2Array()
  59. for y in range(_map_size.y):
  60. for x in range(_map_size.x):
  61. var point = Vector2(x, y)
  62. if point in p_obstacle_positions:
  63. continue
  64.  
  65. points_array.append(point)
  66. # The AStar class references points with indices
  67. # Using a function to calculate the index from a point's coordinates
  68. # ensures we always get the same index with the same input point
  69. var point_index = calculate_point_index(point)
  70. # AStar works for both 2d and 3d, so we have to convert the point
  71. # coordinates from and to Vector3s
  72. self.astar.add_point(point_index, Vector3(point.x, point.y, 0))
  73. return points_array
  74.  
  75.  
  76. func astar_connect_walkable_cells(p_points_array: PoolVector2Array) -> void:
  77. for point in p_points_array:
  78. var point_index = calculate_point_index(point)
  79. # For every cell in the map, we check the one to the top, right.
  80. # left and bottom of it. If it's in the map and not an obstalce,
  81. # We connect the current point with it
  82. var points_relative = PoolVector2Array([
  83. Vector2(point.x + 1, point.y),
  84. Vector2(point.x - 1, point.y),
  85. Vector2(point.x, point.y + 1),
  86. Vector2(point.x, point.y - 1)])
  87. for point_relative in points_relative:
  88. var point_relative_index = calculate_point_index(point_relative)
  89.  
  90. if is_outside_map_bounds(point_relative):
  91. continue
  92. if not self.astar.has_point(point_relative_index):
  93. continue
  94. # Note the 3rd argument. It tells the self.astar that we want the
  95. # connection to be bilateral: from point A to B and B to A
  96. # If you set this value to false, it becomes a one-way path
  97. # As we loop through all points we can set it to false
  98. self.astar.connect_points(point_index, point_relative_index, false)
  99.  
  100.  
  101. func is_outside_map_bounds(p_point: Vector2) -> bool:
  102. var r : bool = p_point.x < 0 or p_point.y < 0 or p_point.x >= _map_size.x or p_point.y >= _map_size.y
  103. return r
  104.  
  105.  
  106. func calculate_point_index(p_point: Vector2) -> int:
  107. var r: int = p_point.x + _map_size.x * p_point.y
  108. return r
  109.  
  110.  
  111. func get_path(p_start_position: Vector2, p_end_position: Vector2) -> PoolVector2Array:
  112. _recalculate_path(p_start_position, p_end_position)
  113. var path_world : PoolVector2Array = PoolVector2Array()
  114. for point in _point_path:
  115. var point_world = _tile_map.map_to_world(Vector2(point.x, point.y)) + _half_cell_size
  116. path_world.append(point_world)
  117. return path_world
  118.  
  119.  
  120. func _recalculate_path(p_start_position: Vector2, p_end_position: Vector2) -> void:
  121.  
  122. # WRONG LINES
  123. #var start_point_index: = calculate_point_index(p_start_position)
  124. #var end_point_index: = calculate_point_index(p_end_position)
  125.  
  126. # FIXED LINES
  127. var start_point_index: = calculate_point_index(_tile_map.world_to_map(p_start_position))
  128. var end_point_index: = calculate_point_index(_tile_map.world_to_map(p_end_position))
  129.  
  130. # This method gives us an array of points. Note you need the start and end
  131. # points' indices as input
  132. _point_path = self.astar.get_point_path(start_point_index, end_point_index)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement