actor.py 3.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. # coding: utf-8
  2. import typing
  3. import pyglet
  4. import cocos
  5. from cocos import collision_model
  6. from cocos import euclid
  7. from synergine2.config import Config
  8. from synergine2.simulation import Subject
  9. from synergine2_cocos2d.animation import AnimatedInterface
  10. from synergine2_cocos2d.util import PathManager
  11. class Actor(AnimatedInterface, cocos.sprite.Sprite):
  12. animation_image_paths = {} # type: typing.Dict[str, typing.List[str]]
  13. def __init__(
  14. self,
  15. image_path: str,
  16. subject: Subject,
  17. position=(0, 0),
  18. rotation=0,
  19. scale=1,
  20. opacity=255,
  21. color=(255, 255, 255),
  22. anchor=None,
  23. properties: dict=None,
  24. config: Config=None,
  25. **kwargs
  26. ):
  27. # Note: Parameter required, but we want to modify little as possible parent init
  28. assert config, "Config is a required parameter"
  29. self.path_manager = PathManager(config.resolve('global.include_path.graphics'))
  30. image = pyglet.resource.image(self.path_manager.path(image_path))
  31. self.animation_images = {} # type: typing.Dict[str, typing.List[pyglet.image.TextureRegion]] # nopep8
  32. super().__init__(
  33. image,
  34. position,
  35. rotation,
  36. scale,
  37. opacity,
  38. color,
  39. anchor,
  40. **kwargs
  41. )
  42. self.subject = subject
  43. self.cshape = None # type: collision_model.AARectShape
  44. self.update_cshape()
  45. self.build_animation_images()
  46. self.current_image = image
  47. self.need_update_cshape = False
  48. self.properties = properties or {}
  49. self._freeze = False
  50. def freeze(self) -> None:
  51. """
  52. Set object to freeze mode: No visual modification can be done anymore
  53. """
  54. self._freeze = True
  55. def stop_actions(self, action_types: typing.Tuple[typing.Type[cocos.actions.Action], ...]) -> None:
  56. for action in self.actions:
  57. if isinstance(action, action_types):
  58. self.remove_action(action)
  59. def update_cshape(self) -> None:
  60. self.cshape = collision_model.AARectShape(
  61. euclid.Vector2(self.position[0], self.position[1]),
  62. self.width // 2,
  63. self.height // 2,
  64. )
  65. self.need_update_cshape = False
  66. def update_position(self, new_position: euclid.Vector2) -> None:
  67. if self._freeze:
  68. return
  69. self.position = new_position
  70. self.cshape.center = new_position # Note: if remove: strange behaviour: drag change actor position with anomaly
  71. def build_animation_images(self) -> None:
  72. """
  73. Fill self.animation_images with self.animation_image_paths
  74. :return: None
  75. """
  76. for animation_name, animation_image_paths in self.animation_image_paths.items():
  77. self.animation_images[animation_name] = []
  78. for animation_image_path in animation_image_paths:
  79. final_image_path = self.path_manager.path(animation_image_path)
  80. self.animation_images[animation_name].append(
  81. pyglet.resource.image(
  82. final_image_path,
  83. )
  84. )
  85. def get_images_for_animation(self, animation_name: str) -> typing.List[pyglet.image.TextureRegion]:
  86. return self.animation_images.get(animation_name)
  87. def get_inanimate_image(self) -> pyglet.image.TextureRegion:
  88. return self.current_image
  89. def update_image(self, new_image: pyglet.image.TextureRegion):
  90. if self._freeze:
  91. return
  92. self.image = new_image
  93. self.image_anchor = new_image.width // 2, new_image.height // 2