Bläddra i källkod

engulf: cel movement

Bastien Sevajol 7 år sedan
förälder
incheckning
814ddaf2dc

+ 6 - 0
requirements.txt Visa fil

1
+appdirs==1.4.2
1
 cocos2d==0.6.4
2
 cocos2d==0.6.4
3
+packaging==16.8
4
+pkg-resources==0.0.0
2
 py==1.4.31
5
 py==1.4.31
3
 pyglet==1.2.4
6
 pyglet==1.2.4
7
+pymlconf==0.7.0
8
+pyparsing==2.1.10
4
 pytest==3.0.4
9
 pytest==3.0.4
10
+PyYAML==3.12
5
 six==1.10.0
11
 six==1.10.0

+ 60 - 1
sandbox/engulf/behaviour.py Visa fil

1
 # coding: utf-8
1
 # coding: utf-8
2
+from random import randint
3
+
4
+from sandbox.engulf.const import COLLECTION_GRASS
2
 from synergine2.simulation import SubjectBehaviour, SimulationMechanism, SimulationBehaviour
5
 from synergine2.simulation import SubjectBehaviour, SimulationMechanism, SimulationBehaviour
3
 from synergine2.simulation import Event
6
 from synergine2.simulation import Event
4
 from synergine2.utils import ChunkManager
7
 from synergine2.utils import ChunkManager
5
-from synergine2.xyz_utils import get_around_positions_of_positions
8
+from synergine2.xyz import ProximitySubjectMechanism
9
+from synergine2.xyz_utils import get_around_positions_of_positions, get_around_positions_of
6
 
10
 
7
 
11
 
8
 class GrassGrownUp(Event):
12
 class GrassGrownUp(Event):
115
                 ))
119
                 ))
116
 
120
 
117
         return events
121
         return events
122
+
123
+
124
+class EatableDirectProximityMechanism(ProximitySubjectMechanism):
125
+    distance = 1.41  # distance when on angle
126
+    feel_collections = [COLLECTION_GRASS]
127
+
128
+
129
+class MoveTo(Event):
130
+    def __init__(self, subject_id: int, position: tuple, *args, **kwargs):
131
+        super().__init__(*args, **kwargs)
132
+        self.subject_id = subject_id
133
+        self.position = position
134
+
135
+    def repr_debug(self) -> str:
136
+        return '{}: subject_id:{}, position:{}'.format(
137
+            type(self).__name__,
138
+            self.subject_id,
139
+            self.position,
140
+        )
141
+
142
+
143
+class SearchFood(SubjectBehaviour):
144
+    """
145
+    Si une nourriture a une case de distance et cellule non rassasié, move dans sa direction.
146
+    """
147
+    use = [EatableDirectProximityMechanism]
148
+
149
+    def run(self, data):
150
+        pass
151
+
152
+
153
+class Eat(SubjectBehaviour):
154
+    """
155
+    Prduit un immobilisme si sur une case de nourriture, dans le cas ou la cellule n'est as rassasié.
156
+    """
157
+    def run(self, data):
158
+        pass
159
+
160
+
161
+class Explore(SubjectBehaviour):
162
+    """
163
+    Produit un mouvement au hasard (ou un immobilisme)
164
+    """
165
+    use = []
166
+
167
+    def action(self, data) -> [Event]:
168
+        position = self.get_random_around_position()
169
+        return [MoveTo(self.subject.id, position)]
170
+
171
+    def run(self, data):
172
+        return True  # for now, want move every time
173
+
174
+    def get_random_around_position(self):
175
+        around_positions = get_around_positions_of(self.subject.position)
176
+        return around_positions[randint(0, len(around_positions)-1)]

+ 4 - 0
sandbox/engulf/config.yaml Visa fil

1
+core:
2
+    cycle_duration: 0.5
3
+terminals:
4
+    sync: True

+ 7 - 0
sandbox/engulf/const.py Visa fil

1
+# coding: utf-8
2
+
3
+
4
+COLLECTION_CELL = 'CELL'
5
+COLLECTION_ALIVE = 'ALIVE'
6
+COLLECTION_EATABLE = 'EATABLE'
7
+COLLECTION_GRASS = 'GRASS'

+ 50 - 11
sandbox/engulf/gui.py Visa fil

2
 from random import randint
2
 from random import randint
3
 
3
 
4
 import cocos
4
 import cocos
5
+from cocos.actions import MoveTo, Repeat, ScaleBy, Reverse, RotateTo
5
 from cocos.sprite import Sprite
6
 from cocos.sprite import Sprite
6
-from sandbox.engulf.behaviour import GrassGrownUp, GrassSpawn
7
+from sandbox.engulf.behaviour import GrassGrownUp, GrassSpawn, MoveTo as MoveToEvent
7
 from sandbox.engulf.subject import Cell, Grass
8
 from sandbox.engulf.subject import Cell, Grass
8
 from synergine2.terminals import TerminalPackage
9
 from synergine2.terminals import TerminalPackage
9
 from synergine2_cocos2d.gui import Gui, GridLayerMixin
10
 from synergine2_cocos2d.gui import Gui, GridLayerMixin
10
 from synergine2_cocos2d.gui import MainLayer as BaseMainLayer
11
 from synergine2_cocos2d.gui import MainLayer as BaseMainLayer
11
 
12
 
13
+cell_scale = ScaleBy(1.1, duration=0.25)
14
+
12
 
15
 
13
 class CellsLayer(GridLayerMixin, BaseMainLayer):
16
 class CellsLayer(GridLayerMixin, BaseMainLayer):
14
-    def __init__(self, *args, **kwargs):
17
+    def __init__(self, game: 'Game', *args, **kwargs):
15
         super().__init__(*args, **kwargs)
18
         super().__init__(*args, **kwargs)
16
-        self.cells = {}
19
+        self.game = game
20
+        self.cell_positions = {}
21
+        self.cell_ids = {}
22
+
23
+    @property
24
+    def move_duration(self):
25
+        return self.game.cycle_duration
26
+
27
+    @property
28
+    def fake_move_rotate_duration(self):
29
+        return self.move_duration / 3
17
 
30
 
18
-    def born(self, grid_position):
31
+    def born(self, subject_id: int, grid_position):
19
         cell = Sprite('resources/cell.png')
32
         cell = Sprite('resources/cell.png')
20
         cell.rotation = randint(0, 360)
33
         cell.rotation = randint(0, 360)
21
         self.grid_manager.scale_sprite(cell)
34
         self.grid_manager.scale_sprite(cell)
22
         self.grid_manager.position_sprite(cell, grid_position)
35
         self.grid_manager.position_sprite(cell, grid_position)
23
-        self.cells[grid_position] = cell
36
+        self.cell_positions[grid_position] = cell
37
+        self.cell_ids[subject_id] = cell
38
+        cell.do(Repeat(cell_scale + Reverse(cell_scale)))
24
         self.add(cell)
39
         self.add(cell)
25
 
40
 
41
+    def move(self, subject_id: int, position: tuple):
42
+        cell = self.cell_ids[subject_id]
43
+
44
+        window_position = self.grid_manager.get_window_position(position[0], position[1])
45
+        move_action = MoveTo(window_position, self.move_duration)
46
+
47
+        fake_rotate = RotateTo(randint(0, 360), self.fake_move_rotate_duration)
48
+
49
+        cell.do(move_action)
50
+        cell.do(fake_rotate)
51
+
26
 
52
 
27
 class GrassLayer(GridLayerMixin, BaseMainLayer):
53
 class GrassLayer(GridLayerMixin, BaseMainLayer):
28
-    def __init__(self, *args, **kwargs):
54
+    def __init__(self, game: 'Game', *args, **kwargs):
29
         super().__init__(*args, **kwargs)
55
         super().__init__(*args, **kwargs)
56
+        self.game = game
30
         self.grasses = {}
57
         self.grasses = {}
31
 
58
 
32
     def born(self, subject_id, grid_position, opacity=100):
59
     def born(self, subject_id, grid_position, opacity=100):
43
 
70
 
44
 
71
 
45
 class MainLayer(GridLayerMixin, BaseMainLayer):
72
 class MainLayer(GridLayerMixin, BaseMainLayer):
46
-    def __init__(self, terminal, *args, **kwargs):
73
+    def __init__(self, game: 'Game', terminal, *args, **kwargs):
47
         super().__init__(terminal, *args, **kwargs)
74
         super().__init__(terminal, *args, **kwargs)
75
+        self.game = game
48
 
76
 
49
-        self.cells = CellsLayer(terminal=terminal)
77
+        self.cells = CellsLayer(game=game, terminal=terminal)
50
         self.add(self.cells)
78
         self.add(self.cells)
51
 
79
 
52
-        self.grasses = GrassLayer(terminal=terminal)
80
+        self.grasses = GrassLayer(game=game, terminal=terminal)
53
         self.add(self.grasses)
81
         self.add(self.grasses)
54
 
82
 
55
 
83
 
57
     def __init__(self, *args, **kwargs):
85
     def __init__(self, *args, **kwargs):
58
         super().__init__(*args, **kwargs)
86
         super().__init__(*args, **kwargs)
59
 
87
 
60
-        self.main_layer = MainLayer(terminal=self.terminal)
88
+        self.main_layer = MainLayer(game=self, terminal=self.terminal)
61
         self.main_scene = cocos.scene.Scene(self.main_layer)
89
         self.main_scene = cocos.scene.Scene(self.main_layer)
62
 
90
 
91
+        # Event registering
63
         self.terminal.register_event_handler(
92
         self.terminal.register_event_handler(
64
             GrassGrownUp,
93
             GrassGrownUp,
65
             self.on_grass_grown_up,
94
             self.on_grass_grown_up,
68
             GrassSpawn,
97
             GrassSpawn,
69
             self.on_grass_spawn,
98
             self.on_grass_spawn,
70
         )
99
         )
100
+        self.terminal.register_event_handler(
101
+            MoveToEvent,
102
+            self.on_move_to,
103
+        )
71
 
104
 
72
     def get_main_scene(self):
105
     def get_main_scene(self):
73
         return self.main_scene
106
         return self.main_scene
76
         if package.subjects:  # It's thirst package
109
         if package.subjects:  # It's thirst package
77
             for subject in package.subjects:
110
             for subject in package.subjects:
78
                 if isinstance(subject, Cell):
111
                 if isinstance(subject, Cell):
79
-                    self.main_layer.cells.born(subject.position)
112
+                    self.main_layer.cells.born(subject.id, subject.position)
80
                 if isinstance(subject, Grass):
113
                 if isinstance(subject, Grass):
81
                     self.main_layer.grasses.born(
114
                     self.main_layer.grasses.born(
82
                         subject.id,
115
                         subject.id,
96
             event.subject_id,
129
             event.subject_id,
97
             event.density,  # TODO: Recupe ces données depuis local plutôt que event ?
130
             event.density,  # TODO: Recupe ces données depuis local plutôt que event ?
98
         )
131
         )
132
+
133
+    def on_move_to(self, event: MoveToEvent):
134
+        self.main_layer.cells.move(
135
+            event.subject_id,
136
+            event.position,
137
+        )

+ 10 - 4
sandbox/engulf/run.py Visa fil

27
 sys.path.append(synergine2_ath)
27
 sys.path.append(synergine2_ath)
28
 
28
 
29
 from random import randint, seed
29
 from random import randint, seed
30
-from sandbox.engulf.behaviour import GrassGrownUp, GrassSpawn, GrassSpawnBehaviour
30
+from sandbox.engulf.behaviour import GrassGrownUp, GrassSpawn, GrassSpawnBehaviour, MoveTo
31
 
31
 
32
 from synergine2.config import Config
32
 from synergine2.config import Config
33
 from synergine2.log import get_default_logger
33
 from synergine2.log import get_default_logger
34
-from sandbox.engulf.subject import Cell, Grass, COLLECTION_GRASS
34
+from sandbox.engulf.subject import Cell, Grass
35
+from sandbox.engulf.const import COLLECTION_GRASS
35
 from synergine2.core import Core
36
 from synergine2.core import Core
36
 from synergine2.cycle import CycleManager
37
 from synergine2.cycle import CycleManager
37
 from synergine2.terminals import TerminalManager, Terminal, TerminalPackage
38
 from synergine2.terminals import TerminalManager, Terminal, TerminalPackage
50
     subscribed_events = [
51
     subscribed_events = [
51
         GrassGrownUp,
52
         GrassGrownUp,
52
         GrassSpawn,
53
         GrassSpawn,
54
+        MoveTo,
53
     ]
55
     ]
54
 
56
 
55
     def __init__(self, *args, **kwargs):
57
     def __init__(self, *args, **kwargs):
56
         super().__init__(*args, **kwargs)
58
         super().__init__(*args, **kwargs)
57
         self.gui = None
59
         self.gui = None
60
+        self.asynchronous = False  # TODO: config
58
 
61
 
59
     def receive(self, package: TerminalPackage):
62
     def receive(self, package: TerminalPackage):
60
         self.gui.before_received(package)
63
         self.gui.before_received(package)
63
 
66
 
64
     def run(self):
67
     def run(self):
65
         from sandbox.engulf import gui
68
         from sandbox.engulf import gui
66
-        self.gui = gui.Game(self)
69
+        self.gui = gui.Game(self.config, self.logger, self)
67
         self.gui.run()
70
         self.gui.run()
68
 
71
 
69
 
72
 
145
     simulation.subjects = subjects
148
     simulation.subjects = subjects
146
 
149
 
147
     config = Config()
150
     config = Config()
151
+    config.load_files(['sandbox/engulf/config.yaml'])
148
     logger = get_default_logger(level=logging.DEBUG)
152
     logger = get_default_logger(level=logging.DEBUG)
149
 
153
 
150
     core = Core(
154
     core = Core(
160
             config=config,
164
             config=config,
161
             logger=logger,
165
             logger=logger,
162
             terminals=[GameTerminal(
166
             terminals=[GameTerminal(
167
+                config,
168
+                logger,
163
                 asynchronous=False,
169
                 asynchronous=False,
164
             )]
170
             )]
165
         ),
171
         ),
166
-        cycles_per_seconds=1,
172
+        cycles_per_seconds=1/config.core.cycle_duration,
167
     )
173
     )
168
     core.run()
174
     core.run()
169
 
175
 

+ 7 - 6
sandbox/engulf/subject.py Visa fil

1
 # coding: utf-8
1
 # coding: utf-8
2
-from sandbox.engulf.behaviour import GrowUp
2
+from sandbox.engulf.behaviour import GrowUp, SearchFood, Eat, Explore
3
+from sandbox.engulf.const import COLLECTION_CELL, COLLECTION_ALIVE, COLLECTION_EATABLE, COLLECTION_GRASS
3
 from synergine2.simulation import Subject
4
 from synergine2.simulation import Subject
4
 from synergine2.xyz import XYZSubjectMixin
5
 from synergine2.xyz import XYZSubjectMixin
5
 
6
 
6
-COLLECTION_CELL = 'CELL'
7
-COLLECTION_ALIVE = 'ALIVE'
8
-COLLECTION_EATABLE = 'EATABLE'
9
-COLLECTION_GRASS = 'GRASS'
10
-
11
 
7
 
12
 class Cell(XYZSubjectMixin, Subject):
8
 class Cell(XYZSubjectMixin, Subject):
13
     collections = [
9
     collections = [
15
         COLLECTION_ALIVE,
11
         COLLECTION_ALIVE,
16
         COLLECTION_EATABLE,
12
         COLLECTION_EATABLE,
17
     ]
13
     ]
14
+    behaviours_classes = [
15
+        SearchFood,
16
+        Eat,
17
+        Explore,
18
+    ]
18
 
19
 
19
 
20
 
20
 class Grass(XYZSubjectMixin, Subject):
21
 class Grass(XYZSubjectMixin, Subject):

+ 5 - 1
sandbox/life_game/gui.py Visa fil

9
 from sandbox.life_game.simulation import CellBornEvent
9
 from sandbox.life_game.simulation import CellBornEvent
10
 from sandbox.life_game.simulation import CellDieEvent, Cell, InvertCellStateBehaviour, \
10
 from sandbox.life_game.simulation import CellDieEvent, Cell, InvertCellStateBehaviour, \
11
     EmptyPositionWithLotOfCellAroundEvent
11
     EmptyPositionWithLotOfCellAroundEvent
12
+from synergine2.config import Config
13
+from synergine2.log import SynergineLogger
12
 from synergine2.terminals import Terminal
14
 from synergine2.terminals import Terminal
13
 from synergine2.terminals import TerminalPackage
15
 from synergine2.terminals import TerminalPackage
14
 from synergine2_cocos2d.gui import Gui, GridLayerMixin, MainLayer as BaseMainLayer
16
 from synergine2_cocos2d.gui import Gui, GridLayerMixin, MainLayer as BaseMainLayer
100
 class LifeGameGui(Gui):
102
 class LifeGameGui(Gui):
101
     def __init__(
103
     def __init__(
102
             self,
104
             self,
105
+            config: Config,
106
+            logger: SynergineLogger,
103
             terminal: Terminal,
107
             terminal: Terminal,
104
             read_queue_interval: float=1 / 60.0,
108
             read_queue_interval: float=1 / 60.0,
105
     ):
109
     ):
106
-        super().__init__(terminal, read_queue_interval)
110
+        super().__init__(config, logger, terminal, read_queue_interval)
107
 
111
 
108
         self.main_layer = MainLayer(terminal=self.terminal)
112
         self.main_layer = MainLayer(terminal=self.terminal)
109
         self.main_scene = cocos.scene.Scene(self.main_layer)
113
         self.main_scene = cocos.scene.Scene(self.main_layer)

+ 9 - 6
sandbox/life_game/run.py Visa fil

34
         CellBornEvent,
34
         CellBornEvent,
35
     ]
35
     ]
36
 
36
 
37
-    def __init__(self):
38
-        super().__init__()
37
+    def __init__(self, *args, **kwargs):
38
+        super().__init__(*args, **kwargs)
39
         self._cycle_born_count = 0
39
         self._cycle_born_count = 0
40
         self._cycle_die_count = 0
40
         self._cycle_die_count = 0
41
         self.register_event_handler(CellDieEvent, self.record_die)
41
         self.register_event_handler(CellDieEvent, self.record_die)
86
         EmptyPositionWithLotOfCellAroundEvent,
86
         EmptyPositionWithLotOfCellAroundEvent,
87
     ]
87
     ]
88
 
88
 
89
-    def __init__(self):
90
-        super().__init__()
89
+    def __init__(self, *args, **kwargs):
90
+        super().__init__(*args, **kwargs)
91
         self.subjects = None
91
         self.subjects = None
92
         self.gui = None
92
         self.gui = None
93
 
93
 
98
 
98
 
99
     def run(self):
99
     def run(self):
100
         from sandbox.life_game import gui
100
         from sandbox.life_game import gui
101
-        self.gui = gui.LifeGameGui(self)
101
+        self.gui = gui.LifeGameGui(self.config, self.logger, self)
102
         self.gui.run()
102
         self.gui.run()
103
 
103
 
104
 
104
 
146
         terminal_manager=TerminalManager(
146
         terminal_manager=TerminalManager(
147
             config=config,
147
             config=config,
148
             logger=logger,
148
             logger=logger,
149
-            terminals=[CocosTerminal(), SimplePrintTerminal()]
149
+            terminals=[
150
+                CocosTerminal(config, logger),
151
+                SimplePrintTerminal(config, logger),
152
+            ]
150
         ),
153
         ),
151
     )
154
     )
152
     core.run()
155
     core.run()

+ 2 - 1
synergine2/config.py Visa fil

1
 # coding: utf-8
1
 # coding: utf-8
2
+from pymlconf import ConfigManager
2
 
3
 
3
 
4
 
4
-class Config(dict):
5
+class Config(ConfigManager):
5
     pass
6
     pass

+ 8 - 1
synergine2/terminals.py Visa fil

59
     # who are not instance of listed classes
59
     # who are not instance of listed classes
60
     subscribed_events = [Event]
60
     subscribed_events = [Event]
61
 
61
 
62
-    def __init__(self, asynchronous: bool=True):
62
+    def __init__(
63
+        self,
64
+        config: Config,
65
+        logger: SynergineLogger,
66
+        asynchronous: bool=True,
67
+    ):
68
+        self.config = config
69
+        self.logger = logger
63
         self._input_queue = None
70
         self._input_queue = None
64
         self._output_queue = None
71
         self._output_queue = None
65
         self._stop_required = False
72
         self._stop_required = False

+ 7 - 0
synergine2_cocos2d/gui.py Visa fil

6
 from cocos.layer import ScrollableLayer, Layer
6
 from cocos.layer import ScrollableLayer, Layer
7
 from cocos.sprite import Sprite
7
 from cocos.sprite import Sprite
8
 
8
 
9
+from synergine2.config import Config
10
+from synergine2.log import SynergineLogger
9
 from synergine2.terminals import Terminal
11
 from synergine2.terminals import Terminal
10
 from synergine2.terminals import TerminalPackage
12
 from synergine2.terminals import TerminalPackage
11
 
13
 
106
 class Gui(object):
108
 class Gui(object):
107
     def __init__(
109
     def __init__(
108
             self,
110
             self,
111
+            config: Config,
112
+            logger: SynergineLogger,
109
             terminal: Terminal,
113
             terminal: Terminal,
110
             read_queue_interval: float= 1/60.0,
114
             read_queue_interval: float= 1/60.0,
111
     ):
115
     ):
116
+        self.config = config
117
+        self.logger = logger,
112
         self._read_queue_interval = read_queue_interval
118
         self._read_queue_interval = read_queue_interval
113
         self.terminal = terminal
119
         self.terminal = terminal
120
+        self.cycle_duration = self.config.core.cycle_duration
114
         cocos.director.director.init()
121
         cocos.director.director.init()
115
 
122
 
116
     def run(self):
123
     def run(self):