animation.py 2.9KB

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