gui.py 5.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. # coding: utf-8
  2. from random import randint
  3. import cocos
  4. from cocos.actions import MoveTo, Repeat, ScaleBy, Reverse, RotateTo
  5. from cocos.sprite import Sprite
  6. from sandbox.engulf.behaviour import GrassGrownUp, GrassSpawn, MoveTo as MoveToEvent, EatEvent, AttackEvent, EatenEvent
  7. from sandbox.engulf.subject import Cell, Grass, PreyCell, PredatorCell
  8. from synergine2.terminals import TerminalPackage, Terminal
  9. from synergine2_cocos2d.gui import Gui, GridLayerMixin
  10. from synergine2_cocos2d.gui import MainLayer as BaseMainLayer
  11. cell_scale = ScaleBy(1.1, duration=0.25)
  12. class CellsLayer(GridLayerMixin, BaseMainLayer):
  13. def __init__(self, game: 'Game', *args, **kwargs):
  14. super().__init__(*args, **kwargs)
  15. self.game = game
  16. self.cell_positions = {}
  17. self.cell_ids = {}
  18. @property
  19. def move_duration(self):
  20. return self.game.cycle_duration
  21. @property
  22. def fake_move_rotate_duration(self):
  23. return self.move_duration / 3
  24. def born(self, subject_id: int, grid_position, cell_type):
  25. png = 'resources/cell.png' if cell_type is PreyCell else 'resources/cellp.png'
  26. cell = Sprite(png)
  27. cell.rotation = randint(0, 360)
  28. self.grid_manager.scale_sprite(cell)
  29. self.grid_manager.position_sprite(cell, grid_position)
  30. self.cell_positions[grid_position] = cell
  31. self.cell_ids[subject_id] = cell
  32. cell.do(Repeat(cell_scale + Reverse(cell_scale)))
  33. self.add(cell)
  34. def move(self, subject_id: int, position: tuple):
  35. if subject_id not in self.cell_ids:
  36. return # Cell eaten before
  37. cell = self.cell_ids[subject_id]
  38. window_position = self.grid_manager.get_window_position(position[0], position[1])
  39. move_action = MoveTo(window_position, self.move_duration)
  40. fake_rotate = RotateTo(randint(0, 360), self.fake_move_rotate_duration)
  41. cell.do(move_action)
  42. cell.do(fake_rotate)
  43. def attack(self, attacker_id: int, attacked_id: int):
  44. attacker = self.cell_ids[attacker_id]
  45. attacker.do(ScaleBy(1.7, duration=0.25))
  46. def eaten(self, eaten_id: int):
  47. eaten = self.cell_ids[eaten_id]
  48. self.remove(eaten)
  49. # TODO: refact: On a pas nettoyer self.cell_positions par exemple
  50. del self.cell_ids[eaten_id]
  51. class GrassLayer(GridLayerMixin, BaseMainLayer):
  52. def __init__(self, game: 'Game', *args, **kwargs):
  53. super().__init__(*args, **kwargs)
  54. self.game = game
  55. self.grasses = {}
  56. def born(self, subject_id, grid_position, opacity=100):
  57. grass = Sprite('resources/grass.png')
  58. grass.rotation = randint(0, 360)
  59. grass.opacity = opacity
  60. self.grid_manager.scale_sprite(grass)
  61. self.grid_manager.position_sprite(grass, grid_position)
  62. self.grasses[subject_id] = grass
  63. self.add(grass)
  64. def set_density(self, subject_id, density):
  65. self.grasses[subject_id].opacity = density
  66. class MainLayer(GridLayerMixin, BaseMainLayer):
  67. def __init__(self, game: 'Game', terminal: Terminal, *args, **kwargs):
  68. super().__init__(terminal, *args, **kwargs)
  69. self.game = game
  70. self.terminal = terminal
  71. self.cells = CellsLayer(game=game, terminal=terminal)
  72. self.add(self.cells)
  73. self.grasses = GrassLayer(game=game, terminal=terminal)
  74. self.add(self.grasses)
  75. class Game(Gui):
  76. def __init__(self, *args, **kwargs):
  77. super().__init__(*args, **kwargs)
  78. self.main_layer = MainLayer(game=self, terminal=self.terminal)
  79. self.main_scene = cocos.scene.Scene(self.main_layer)
  80. # Event registering
  81. self.terminal.register_event_handler(
  82. GrassGrownUp,
  83. self.on_grass_grown_up,
  84. )
  85. self.terminal.register_event_handler(
  86. GrassSpawn,
  87. self.on_grass_spawn,
  88. )
  89. self.terminal.register_event_handler(
  90. MoveToEvent,
  91. self.on_move_to,
  92. )
  93. self.terminal.register_event_handler(
  94. EatEvent,
  95. self.on_eat,
  96. )
  97. self.terminal.register_event_handler(
  98. AttackEvent,
  99. self.on_attack,
  100. )
  101. self.terminal.register_event_handler(
  102. EatenEvent,
  103. self.on_eaten,
  104. )
  105. def get_main_scene(self):
  106. return self.main_scene
  107. def before_received(self, package: TerminalPackage):
  108. if package.subjects: # It's thirst package
  109. for subject in package.subjects:
  110. if isinstance(subject, PreyCell):
  111. self.main_layer.cells.born(subject.id, subject.position, PreyCell)
  112. if isinstance(subject, PredatorCell):
  113. self.main_layer.cells.born(subject.id, subject.position, PredatorCell)
  114. if isinstance(subject, Grass):
  115. self.main_layer.grasses.born(
  116. subject.id,
  117. subject.position,
  118. subject.density,
  119. )
  120. def on_grass_spawn(self, event: GrassSpawn):
  121. self.main_layer.grasses.born(
  122. event.subject_id,
  123. event.position,
  124. event.density,
  125. )
  126. def on_grass_grown_up(self, event: GrassGrownUp):
  127. self.main_layer.grasses.set_density(
  128. event.subject_id,
  129. event.density, # TODO: Recupe ces données depuis local plutôt que event ?
  130. )
  131. def on_move_to(self, event: MoveToEvent):
  132. self.main_layer.cells.move(
  133. event.subject_id,
  134. event.position,
  135. )
  136. def on_eat(self, event: EatEvent):
  137. self.main_layer.grasses.set_density(
  138. event.eaten_id,
  139. event.eaten_new_density,
  140. )
  141. def on_attack(self, event: AttackEvent):
  142. self.main_layer.cells.attack(
  143. event.attacker_id,
  144. event.attacked_id,
  145. )
  146. def on_eaten(self, event: EatenEvent):
  147. self.main_layer.cells.eaten(
  148. event.eaten_id,
  149. )