animation.py 3.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. # coding: utf-8
  2. import typing
  3. import pyglet
  4. import cocos
  5. if False:
  6. from synergine2_cocos2d.actor import Actor
  7. ANIMATION_WALK = 'WALK'
  8. ANIMATION_CRAWL = 'CRAWL'
  9. class AnimatedInterface(object):
  10. def get_images_for_animation(self, animation_name: str) -> typing.List[pyglet.image.TextureRegion]:
  11. raise NotImplementedError()
  12. def get_inanimate_image(self) -> pyglet.image.TextureRegion:
  13. """
  14. Use this function to specify what image have to be used when animation is finished.
  15. :return: non inanimate pyglet.image.TextureRegion
  16. """
  17. raise NotImplementedError()
  18. def update_image(self, new_image: pyglet.image.TextureRegion):
  19. raise NotImplementedError()
  20. # TODO: regarder pyglet.image.Animation
  21. class Animate(cocos.actions.IntervalAction):
  22. def __init__(
  23. self,
  24. animation_name: str,
  25. duration: float,
  26. cycle_duration: float,
  27. direction: int=1,
  28. ):
  29. super().__init__()
  30. self.animation_name = animation_name
  31. self.duration = duration
  32. self.animation_images = [] # type: typing.List[pyglet.image.TextureRegion]
  33. self.last_step_elapsed = 0.0 # type: float
  34. self.step_interval = None # type: float
  35. self.cycle_duration = cycle_duration
  36. self.current_step = 0 # typ: int
  37. self.target = typing.cast(AnimatedInterface, self.target)
  38. self.direction = direction
  39. self.reshape = False
  40. def __reversed__(self):
  41. return self.__class__(
  42. self.animation_name,
  43. self.duration,
  44. self.cycle_duration,
  45. self.direction * -1,
  46. )
  47. def set_need_to_reshape(self) -> None:
  48. # TODO: Maybe inanimate_image is not the more appropriate image to refer ?
  49. inanimate_image = self.target.get_inanimate_image()
  50. for position, animation_image in enumerate(self.animation_images):
  51. if animation_image.width != inanimate_image.width or animation_image.height != inanimate_image.height:
  52. self.reshape = True
  53. return
  54. def start(self):
  55. super().start()
  56. self.animation_images = self.target.get_images_for_animation(self.animation_name)
  57. self.step_interval = self.cycle_duration / len(self.animation_images)
  58. self.set_need_to_reshape()
  59. def stop(self):
  60. self.target.update_image(self.target.get_inanimate_image())
  61. super().stop()
  62. def update(self, t):
  63. if not self.is_time_for_new_image():
  64. return
  65. self.current_step += self.direction
  66. try:
  67. new_image = self.animation_images[self.current_step]
  68. except IndexError:
  69. self.current_step = 0
  70. new_image = self.animation_images[0]
  71. self.target.update_image(new_image)
  72. self.last_step_elapsed = self._elapsed
  73. if self.reshape:
  74. self.target.need_update_cshape = True
  75. def is_time_for_new_image(self) -> bool:
  76. return self._elapsed - self.last_step_elapsed >= self.step_interval