gui.py 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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
  7. from sandbox.engulf.subject import Cell, Grass, PreyCell, PredatorCell
  8. from synergine2.terminals import TerminalPackage
  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. cell = self.cell_ids[subject_id]
  36. window_position = self.grid_manager.get_window_position(position[0], position[1])
  37. move_action = MoveTo(window_position, self.move_duration)
  38. fake_rotate = RotateTo(randint(0, 360), self.fake_move_rotate_duration)
  39. cell.do(move_action)
  40. cell.do(fake_rotate)
  41. def attack(self, attacker_id: int, attacked_id: int):
  42. attacker = self.cell_ids[attacker_id]
  43. attacker.do(ScaleBy(1.7, duration=0.25))
  44. class GrassLayer(GridLayerMixin, BaseMainLayer):
  45. def __init__(self, game: 'Game', *args, **kwargs):
  46. super().__init__(*args, **kwargs)
  47. self.game = game
  48. self.grasses = {}
  49. def born(self, subject_id, grid_position, opacity=100):
  50. grass = Sprite('resources/grass.png')
  51. grass.rotation = randint(0, 360)
  52. grass.opacity = opacity
  53. self.grid_manager.scale_sprite(grass)
  54. self.grid_manager.position_sprite(grass, grid_position)
  55. self.grasses[subject_id] = grass
  56. self.add(grass)
  57. def set_density(self, subject_id, density):
  58. self.grasses[subject_id].opacity = density
  59. class MainLayer(GridLayerMixin, BaseMainLayer):
  60. def __init__(self, game: 'Game', terminal, *args, **kwargs):
  61. super().__init__(terminal, *args, **kwargs)
  62. self.game = game
  63. self.cells = CellsLayer(game=game, terminal=terminal)
  64. self.add(self.cells)
  65. self.grasses = GrassLayer(game=game, terminal=terminal)
  66. self.add(self.grasses)
  67. class Game(Gui):
  68. def __init__(self, *args, **kwargs):
  69. super().__init__(*args, **kwargs)
  70. self.main_layer = MainLayer(game=self, terminal=self.terminal)
  71. self.main_scene = cocos.scene.Scene(self.main_layer)
  72. # Event registering
  73. self.terminal.register_event_handler(
  74. GrassGrownUp,
  75. self.on_grass_grown_up,
  76. )
  77. self.terminal.register_event_handler(
  78. GrassSpawn,
  79. self.on_grass_spawn,
  80. )
  81. self.terminal.register_event_handler(
  82. MoveToEvent,
  83. self.on_move_to,
  84. )
  85. self.terminal.register_event_handler(
  86. EatEvent,
  87. self.on_eat,
  88. )
  89. self.terminal.register_event_handler(
  90. AttackEvent,
  91. self.on_attack,
  92. )
  93. def get_main_scene(self):
  94. return self.main_scene
  95. def before_received(self, package: TerminalPackage):
  96. if package.subjects: # It's thirst package
  97. for subject in package.subjects:
  98. if isinstance(subject, PreyCell):
  99. self.main_layer.cells.born(subject.id, subject.position, PreyCell)
  100. if isinstance(subject, PredatorCell):
  101. self.main_layer.cells.born(subject.id, subject.position, PredatorCell)
  102. if isinstance(subject, Grass):
  103. self.main_layer.grasses.born(
  104. subject.id,
  105. subject.position,
  106. subject.density,
  107. )
  108. def on_grass_spawn(self, event: GrassSpawn):
  109. self.main_layer.grasses.born(
  110. event.subject_id,
  111. event.position,
  112. event.density,
  113. )
  114. def on_grass_grown_up(self, event: GrassGrownUp):
  115. self.main_layer.grasses.set_density(
  116. event.subject_id,
  117. event.density, # TODO: Recupe ces données depuis local plutôt que event ?
  118. )
  119. def on_move_to(self, event: MoveToEvent):
  120. self.main_layer.cells.move(
  121. event.subject_id,
  122. event.position,
  123. )
  124. def on_eat(self, event: EatEvent):
  125. self.main_layer.grasses.set_density(
  126. event.eaten_id,
  127. event.eaten_new_density,
  128. )
  129. def on_attack(self, event: AttackEvent):
  130. self.main_layer.cells.attack(
  131. event.attacker_id,
  132. event.attacked_id,
  133. )