Browse Source

move with Dijkstar lib

Bastien Sevajol 6 years ago
parent
commit
5c99ce858d

+ 1 - 0
requirements.txt View File

@@ -2,6 +2,7 @@ apipkg==1.4
2 2
 appdirs==1.4.2
3 3
 cocos2d==0.6.4
4 4
 coverage==4.4.1
5
+Dijkstar==2.2
5 6
 execnet==1.4.1
6 7
 packaging==16.8
7 8
 psutil==5.2.2

+ 2 - 1
sandbox/tile/terminal/base.py View File

@@ -2,11 +2,12 @@
2 2
 from sandbox.tile.simulation.subject import Man as ManSubject
3 3
 from sandbox.tile.gui.actor import Man as ManActor
4 4
 from synergine2_cocos2d.terminal import GameTerminal
5
+from synergine2_xyz.move import MoveEvent
5 6
 
6 7
 
7 8
 class CocosTerminal(GameTerminal):
8 9
     subscribed_events = [
9
-
10
+        MoveEvent,
10 11
     ]
11 12
 
12 13
     def __init__(self, *args, asynchronous: bool, map_dir_path: str, **kwargs):

+ 8 - 0
synergine2_cocos2d/actions.py View File

@@ -0,0 +1,8 @@
1
+# coding: utf-8
2
+from cocos.actions import MoveTo as BaseMoveTo
3
+
4
+
5
+class MoveTo(BaseMoveTo):
6
+    def update(self, t):
7
+        super().update(t)
8
+        self.target.need_update_cshape = True

+ 16 - 0
synergine2_cocos2d/gui.py View File

@@ -15,6 +15,7 @@ from synergine2.config import Config
15 15
 from synergine2.log import SynergineLogger
16 16
 from synergine2.terminals import Terminal
17 17
 from synergine2.terminals import TerminalPackage
18
+from synergine2_cocos2d.actions import MoveTo
18 19
 from synergine2_cocos2d.actor import Actor
19 20
 from synergine2_cocos2d.exception import InteractionNotFound
20 21
 from synergine2_cocos2d.exception import OuterWorldPosition
@@ -25,6 +26,7 @@ from synergine2_cocos2d.layer import LayerManager
25 26
 from synergine2_cocos2d.middleware import MapMiddleware
26 27
 from synergine2_cocos2d.middleware import TMXMiddleware
27 28
 from synergine2_cocos2d.user_action import UserAction
29
+from synergine2_xyz.move import MoveEvent
28 30
 from synergine2_xyz.xyz import XYZSubjectMixin
29 31
 
30 32
 
@@ -739,6 +741,11 @@ class TMXGui(Gui):
739 741
             read_queue_interval,
740 742
         )
741 743
 
744
+        self.terminal.register_event_handler(
745
+            MoveEvent,
746
+            self.move_subject,
747
+        )
748
+
742 749
     def get_layer_middleware(self) -> MapMiddleware:
743 750
         return TMXMiddleware(
744 751
             self.config,
@@ -758,3 +765,12 @@ class TMXGui(Gui):
758 765
     def append_subject(self, subject: XYZSubjectMixin) -> None:
759 766
         subject_mapper = self.subject_mapper_factory.get_subject_mapper(subject)
760 767
         subject_mapper.append(subject, self.layer_manager)
768
+
769
+    def move_subject(self, event: MoveEvent):
770
+        actor = self.layer_manager.subject_layer.subjects_index[event.subject_id]
771
+
772
+        new_world_position = self.layer_manager.grid_manager.get_pixel_position_of_grid_position(event.position)
773
+        new_window_position = self.layer_manager.scrolling_manager.world_to_screen(*new_world_position)
774
+
775
+        move_action = MoveTo(new_window_position, 0.5)
776
+        actor.do(move_action)

+ 13 - 3
synergine2_cocos2d/layer.py View File

@@ -47,6 +47,16 @@ class ScrollingManager(cocos.layer.ScrollingManager):
47 47
         return world_positions
48 48
 
49 49
 
50
+class SubjectLayer(cocos.layer.ScrollableLayer):
51
+    def __init__(self, parallax: int=1):
52
+        super().__init__(parallax)
53
+        self.subjects_index = {}
54
+
55
+    def add_subject(self, actor: 'Actor') -> None:
56
+        self.add(actor)
57
+        self.subjects_index[actor.subject.id] = actor
58
+
59
+
50 60
 class LayerManager(object):
51 61
     def __init__(
52 62
         self,
@@ -68,7 +78,7 @@ class LayerManager(object):
68 78
 
69 79
         self.background_sprite = None  # type: cocos.sprite.Sprite
70 80
         self.ground_layer = None  # type: cocos.tiles.RectMapLayer
71
-        self.subject_layer = None  # type: cocos.layer.ScrollableLayer
81
+        self.subject_layer = None  # type: SubjectLayer
72 82
         self.top_layer = None  # type: cocos.tiles.RectMapLayer
73 83
 
74 84
     def init(self) -> None:
@@ -130,7 +140,7 @@ class LayerManager(object):
130 140
 
131 141
         self.background_sprite = self.middleware.get_background_sprite()
132 142
         self.ground_layer = self.middleware.get_ground_layer()
133
-        self.subject_layer = cocos.layer.ScrollableLayer()
143
+        self.subject_layer = SubjectLayer()
134 144
         self.top_layer = self.middleware.get_top_layer()
135 145
 
136 146
         self.main_layer.add(self.background_sprite)
@@ -145,7 +155,7 @@ class LayerManager(object):
145 155
         self.top_layer.set_view(0, 0, self.top_layer.px_width, self.top_layer.px_height)
146 156
 
147 157
     def add_subject(self, subject: 'Actor') -> None:
148
-        self.subject_layer.add(subject)
158
+        self.subject_layer.add_subject(subject)
149 159
 
150 160
     def remove_subject(self, subject: 'Actor') -> None:
151 161
         self.subject_layer.remove(subject)

+ 30 - 12
synergine2_xyz/move.py View File

@@ -1,6 +1,8 @@
1 1
 # coding: utf-8
2 2
 import typing
3 3
 
4
+from dijkstar import find_path
5
+
4 6
 from synergine2.config import Config
5 7
 from synergine2.simulation import SimulationBehaviour
6 8
 from synergine2.simulation import SubjectBehaviour
@@ -61,18 +63,32 @@ class MoveToMechanism(SubjectMechanism):
61 63
             # TODO: MoveToIntention doit être configurable
62 64
             move = self.subject.intentions.get(MoveToIntention)
63 65
             move = typing.cast(MoveToIntention, move)
64
-            new_path = move.path or None
66
+            new_path = None
65 67
 
66 68
             if not move.path:
67
-                # TODO: Fake to test
68
-                new_path = []
69
-                for i in range(20):
70
-                    new_path.append((
71
-                        self.subject.position[0],
72
-                        self.subject.position[1] + i,
73
-                    ))
74
-
75
-            next_move = new_path[move.path_progression + 1]
69
+                # TODO: Must be XYZSimulation !
70
+                start = '{}.{}'.format(*self.subject.position)
71
+                end = '{}.{}'.format(*move.move_to)
72
+
73
+                found_path = find_path(self.simulation.graph, start, end)
74
+                move.path = []
75
+
76
+                for position in found_path[0]:
77
+                    x, y = map(int, position.split('.'))
78
+                    move.path.append((x, y))
79
+
80
+                # Note: We are in process, move change will be lost
81
+                new_path = move.path
82
+
83
+                # move.path = []
84
+                # new_path = move.path
85
+                # for i in range(20):
86
+                #     move.path.append((
87
+                #         self.subject.position[0],
88
+                #         self.subject.position[1] + i,
89
+                #     ))
90
+
91
+            next_move = move.path[move.path_progression + 1]
76 92
             # TODO: fin de path
77 93
             if not self.simulation.is_possible_position(next_move):
78 94
                 # TODO: refaire le path
@@ -82,7 +98,9 @@ class MoveToMechanism(SubjectMechanism):
82 98
                 'new_path': new_path,
83 99
             }
84 100
 
85
-        except KeyError:
101
+        except IndexError:  # TODO: Specialize ? No movement left
102
+            return None
103
+        except KeyError:  # TODO: Specialize ? No MoveIntention
86 104
             return None
87 105
 
88 106
 
@@ -127,7 +145,7 @@ class MoveToBehaviour(SubjectBehaviour):
127 145
             # TODO: progression et lorsque "vraiment avance d'une case" envoyer le Move
128 146
             # pour le moment on move direct
129 147
             # TODO: fin de path
130
-            move.path_progression += 1  # BUG: ca progresse pas ?
148
+            move.path_progression += 1
131 149
             new_position = move.path[move.path_progression]
132 150
             self.subject.position = new_position
133 151
 

+ 43 - 0
synergine2_xyz/simulation.py View File

@@ -1,6 +1,9 @@
1 1
 # coding: utf-8
2 2
 import typing
3 3
 
4
+from dijkstar import Graph
5
+
6
+from synergine2.config import Config
4 7
 from synergine2.simulation import Simulation as BaseSimulation
5 8
 from synergine2_xyz.subjects import XYZSubjects
6 9
 from synergine2_xyz.subjects import XYZSubject
@@ -9,6 +12,46 @@ from synergine2_xyz.subjects import XYZSubject
9 12
 class XYZSimulation(BaseSimulation):
10 13
     accepted_subject_class = XYZSubjects
11 14
 
15
+    def __init__(
16
+        self,
17
+        config: Config,
18
+    ) -> None:
19
+        super().__init__(config)
20
+        self.graph = Graph()
21
+
22
+        # TODO: Le graph devra être calculé à partir de données comme tmx
23
+        for y in range(40):
24
+            for x in range(70):
25
+                position = '{}.{}'.format(x, y)
26
+                neighbors = []
27
+
28
+                for modifier_x, modifier_y in (
29
+                    (+1, +1),
30
+                    (+1, +0),
31
+                    (+1, -1),
32
+                    (+0, -1),
33
+                    (-1, -1),
34
+                    (-1, +0),
35
+                    (-1, -1),
36
+                    (+0, +1),
37
+                ):
38
+                    try:
39
+                        neighbors.append('{}.{}'.format(x+modifier_x, y+modifier_y))
40
+                    except ValueError:
41
+                        pass
42
+
43
+                for neighbor in neighbors:
44
+                    neighbor_x, neighbor_y = map(int, neighbor.split('.'))
45
+
46
+                    if neighbor_x > 39 or neighbor_x < 0:
47
+                        continue
48
+
49
+                    if neighbor_y > 69 or neighbor_y < 0:
50
+                        continue
51
+
52
+                    # TODO: Voir https://pypi.python.org/pypi/Dijkstar/2.2
53
+                    self.graph.add_edge(position, neighbor, 1)
54
+
12 55
     def is_possible_subject_position(self, subject: XYZSubject, position: tuple) -> bool:
13 56
         return self.is_possible_position(position)
14 57