physics.py 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # coding: utf-8
  2. import typing
  3. from dijkstar import Graph
  4. from dijkstar import find_path
  5. from synergine2.config import Config
  6. from synergine2_xyz.map import TMXMap, XYZTile
  7. from synergine2_xyz.subjects import XYZSubject
  8. from synergine2_xyz.xyz import get_neighbor_positions
  9. class MoveCostComputer(object):
  10. def __init__(
  11. self,
  12. config: Config,
  13. ) -> None:
  14. self.config = config
  15. def for_subject(self, subject: XYZSubject):
  16. # TODO: Verifier ce que sont les parametres pour les nommer correctement
  17. def move_cost_func(previous_node: str, next_node: str, tile: XYZTile, unknown):
  18. return self.compute_move_cost(subject, tile, previous_node, next_node, unknown)
  19. return move_cost_func
  20. def compute_move_cost(
  21. self,
  22. subject: XYZSubject,
  23. tile: XYZTile,
  24. previous_node: str,
  25. next_node: str,
  26. unknown,
  27. ) -> float:
  28. return 1.0
  29. class Physics(object):
  30. move_cost_computer_class = MoveCostComputer
  31. def __init__(
  32. self,
  33. config: Config,
  34. ) -> None:
  35. self.config = config
  36. self.graph = Graph()
  37. self.move_cost_computer = self.move_cost_computer_class(config)
  38. def load(self) -> None:
  39. raise NotImplementedError()
  40. def position_to_key(self, position: typing.Tuple[int, int]) -> str:
  41. return '{}.{}'.format(*position)
  42. def found_path(
  43. self,
  44. start: typing.Tuple[int, int],
  45. end: typing.Tuple[int, int],
  46. subject: XYZSubject,
  47. ) -> typing.List[typing.Tuple[int, int]]:
  48. start_key = self.position_to_key(start)
  49. end_key = self.position_to_key(end)
  50. found_path = find_path(self.graph, start_key, end_key, cost_func=self.move_cost_computer.for_subject(subject))
  51. regular_path = []
  52. for position in found_path[0][1:]:
  53. x, y = map(int, position.split('.'))
  54. regular_path.append((x, y))
  55. return regular_path
  56. class TMXPhysics(Physics):
  57. tmx_map_class = TMXMap
  58. def __init__(
  59. self,
  60. config: Config,
  61. map_file_path: str,
  62. ) -> None:
  63. super().__init__(config)
  64. self.map_file_path = map_file_path
  65. self.tmx_map = self.tmx_map_class(map_file_path)
  66. def load(self) -> None:
  67. self.load_graph_from_map(self.map_file_path)
  68. def load_graph_from_map(self, map_file_path: str) -> None:
  69. # TODO: tmx_map contient tout en cache, faire le dessous en exploitant tmx_map.
  70. for y in range(self.tmx_map.height):
  71. for x in range(self.tmx_map.width):
  72. position = self.position_to_key((x, y))
  73. for neighbor_position in get_neighbor_positions((x, y)):
  74. neighbor = '{}.{}'.format(*neighbor_position)
  75. neighbor_x, neighbor_y = neighbor_position
  76. if neighbor_x > self.tmx_map.width-1 or neighbor_x < 0:
  77. continue
  78. if neighbor_y > self.tmx_map.height-1 or neighbor_y < 0:
  79. continue
  80. # Note: movement consider future tile properties
  81. to_tile = self.tmx_map.layer_tiles('terrain')[neighbor]
  82. # Note: Voir https://pypi.python.org/pypi/Dijkstar/2.2
  83. self.graph.add_edge(position, neighbor, to_tile)