animation.py 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  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. class Animate(cocos.actions.IntervalAction):
  17. def __init__(
  18. self,
  19. animation_name: str,
  20. duration: float,
  21. cycle_duration: float,
  22. direction: int=1,
  23. ):
  24. super().__init__()
  25. self.animation_name = animation_name
  26. self.duration = duration
  27. self.animation_images = [] # type: typing.List[pyglet.image.TextureRegion]
  28. self.last_step_elapsed = 0.0 # type: float
  29. self.step_interval = None # type: float
  30. self.cycle_duration = cycle_duration
  31. self.current_step = 0 # typ: int
  32. self.target = typing.cast(AnimatedInterface, self.target)
  33. self.direction = direction
  34. def __reversed__(self):
  35. return self.__class__(
  36. self.animation_name,
  37. self.duration,
  38. self.cycle_duration,
  39. self.direction * -1,
  40. )
  41. def start(self):
  42. super().start()
  43. self.animation_images = self.target.get_images_for_animation(self.animation_name)
  44. self.step_interval = self.cycle_duration / len(self.animation_images)
  45. def stop(self):
  46. self.target.update_image(self.target.get_inanimate_image())
  47. super().stop()
  48. def update(self, t):
  49. if not self.is_time_for_new_image():
  50. return
  51. self.current_step += self.direction
  52. try:
  53. new_image = self.animation_images[self.current_step]
  54. except IndexError:
  55. self.current_step = 0
  56. new_image = self.animation_images[0]
  57. self.target.update_image(new_image)
  58. self.last_step_elapsed = self._elapsed
  59. def is_time_for_new_image(self) -> bool:
  60. return self._elapsed - self.last_step_elapsed >= self.step_interval