animation_player.nim 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. # author: Ethosa
  2. ## Provides animation in most nodes
  3. import
  4. node,
  5. ../core/enums,
  6. ../thirdparty/opengl
  7. type
  8. AnimationObject* = object
  9. states: seq[tuple[tick: int, value: float]]
  10. obj: ptr float
  11. AnimationPlayerObj* {.final.} = object of NodeObj
  12. objects*: seq[AnimationObject]
  13. duration*: int64
  14. tick*: int64
  15. is_played*: bool
  16. loop*: bool
  17. AnimationPlayerRef* = ref AnimationPlayerObj
  18. proc AnimationPlayer*(name: string = "AnimationPlayer"): AnimationPlayerRef =
  19. runnableExamples:
  20. var animplayer = AnimationPlayer("AnimationPlayer")
  21. nodepattern(AnimationPlayerRef)
  22. result.objects = @[]
  23. result.duration = 180
  24. result.tick = 0
  25. result.is_played = false
  26. result.loop = true
  27. result.kind = ANIMATION_PLAYER_NODE
  28. result.type_of_node = NODE_TYPE_DEFAULT
  29. method addState*(self: AnimationPlayerRef, obj: ptr float, states: seq[tuple[tick: int, value: float]]) {.base.} =
  30. ## Adds a new state to AnimationPlayer.
  31. self.objects.add(AnimationObject(
  32. states: states,
  33. obj: obj
  34. ))
  35. method draw*(self: AnimationPlayerRef, w: GLfloat, h: GLfloat) =
  36. ## This uses in the `window.nim`.
  37. if self.is_played:
  38. if self.tick > self.duration:
  39. self.tick = 0
  40. if not self.loop:
  41. self.is_played = false
  42. return
  43. var
  44. current_states: seq[tuple[tick: int, value: float]] = @[]
  45. current: ptr float
  46. for obj in self.objects:
  47. current = obj.obj
  48. for i in countdown(obj.states.high, 0):
  49. if self.tick >= obj.states[i].tick:
  50. current_states.add(obj.states[i])
  51. break
  52. if current_states.len() == 1:
  53. for i in 0..obj.states.high:
  54. if current_states[0].tick < obj.states[i].tick:
  55. current_states.add(obj.states[i])
  56. break
  57. if current_states.len() == 2:
  58. let
  59. diff_time: float = (current_states[1].tick - current_states[0].tick).float
  60. diff: float = current_states[1].value - current_states[0].value
  61. current[] = current_states[0].value + (self.tick - current_states[0].tick).float/diff_time * diff
  62. echo current[]
  63. current_states = @[]
  64. self.tick += 1
  65. method play*(self: AnimationPlayerRef) {.base.} =
  66. ## Plays animation.
  67. self.is_played = true
  68. method setDuration*(self: AnimationPlayerRef, duration: int) {.base.} =
  69. ## Changes animation duration.
  70. self.duration = duration
  71. method stop*(self: AnimationPlayerRef) {.base.} =
  72. ## Stops animation.
  73. self.is_played = false