# coding: utf-8 import typing from dijkstar import Graph from dijkstar import find_path from synergine2.config import Config from synergine2_xyz.map import TMXMap, XYZTile from synergine2_xyz.subjects import XYZSubject from synergine2_xyz.xyz import get_neighbor_positions class MoveCostComputer(object): def __init__( self, config: Config, ) -> None: self.config = config def for_subject(self, subject: XYZSubject): # TODO: Verifier ce que sont les parametres pour les nommer correctement def move_cost_func(previous_node: str, next_node: str, tile: XYZTile, unknown): return self.compute_move_cost(subject, tile, previous_node, next_node, unknown) return move_cost_func def compute_move_cost( self, subject: XYZSubject, tile: XYZTile, previous_node: str, next_node: str, unknown, ) -> float: return 1.0 class Physics(object): move_cost_computer_class = MoveCostComputer def __init__( self, config: Config, ) -> None: self.config = config self.graph = Graph() self.move_cost_computer = self.move_cost_computer_class(config) def load(self) -> None: raise NotImplementedError() def position_to_key(self, position: typing.Tuple[int, int]) -> str: return '{}.{}'.format(*position) def found_path( self, start: typing.Tuple[int, int], end: typing.Tuple[int, int], subject: XYZSubject, ) -> typing.List[typing.Tuple[int, int]]: start_key = self.position_to_key(start) end_key = self.position_to_key(end) found_path = find_path(self.graph, start_key, end_key, cost_func=self.move_cost_computer.for_subject(subject)) regular_path = [] for position in found_path[0][1:]: x, y = map(int, position.split('.')) regular_path.append((x, y)) return regular_path class TMXPhysics(Physics): tmx_map_class = TMXMap def __init__( self, config: Config, map_file_path: str, ) -> None: super().__init__(config) self.map_file_path = map_file_path self.tmx_map = self.tmx_map_class(map_file_path) def load(self) -> None: self.load_graph_from_map(self.map_file_path) def load_graph_from_map(self, map_file_path: str) -> None: # TODO: tmx_map contient tout en cache, faire le dessous en exploitant tmx_map. for y in range(self.tmx_map.height): for x in range(self.tmx_map.width): position = self.position_to_key((x, y)) for neighbor_position in get_neighbor_positions((x, y)): neighbor = '{}.{}'.format(*neighbor_position) neighbor_x, neighbor_y = neighbor_position if neighbor_x > self.tmx_map.width-1 or neighbor_x < 0: continue if neighbor_y > self.tmx_map.height-1 or neighbor_y < 0: continue # Note: movement consider future tile properties to_tile = self.tmx_map.layer_tiles('terrain')[neighbor] # Note: Voir https://pypi.python.org/pypi/Dijkstar/2.2 self.graph.add_edge(position, neighbor, to_tile)