animations.nim 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import
  2. math,
  3. sfml, chipmunk,
  4. sg_assets, sfml_stuff, math_helpers
  5. type
  6. PAnimation* = ref TAnimation
  7. TAnimation* = object
  8. sprite*: PSprite
  9. record*: PAnimationRecord
  10. delay*: float
  11. index*: int
  12. direction*: int
  13. spriteRect*: TIntRect
  14. style*: TAnimationStyle
  15. TAnimationStyle* = enum
  16. AnimLoop = 0'i8, AnimBounce, AnimOnce
  17. proc setPos*(obj: PAnimation; pos: TVector) {.inline.}
  18. proc setPos*(obj: PAnimation; pos: TVector2f) {.inline.}
  19. proc setAngle*(obj: PAnimation; radians: float) {.inline.}
  20. proc free*(obj: PAnimation) =
  21. obj.sprite.destroy()
  22. obj.record = nil
  23. proc newAnimation*(src: PAnimationRecord; style: TAnimationStyle): PAnimation =
  24. new(result, free)
  25. result.sprite = src.spriteSheet.sprite.copy()
  26. result.record = src
  27. result.delay = src.delay
  28. result.index = 0
  29. result.direction = 1
  30. result.spriteRect = result.sprite.getTextureRect()
  31. result.style = style
  32. proc newAnimation*(src: PAnimationRecord; style: TAnimationStyle;
  33. pos: TVector2f; angle: float): PAnimation =
  34. result = newAnimation(src, style)
  35. result.setPos pos
  36. setAngle(result, angle)
  37. proc next*(obj: PAnimation; dt: float): bool {.discardable.} =
  38. ## step the animation. Returns false if the object is out of frames
  39. result = true
  40. obj.delay -= dt
  41. if obj.delay <= 0.0:
  42. obj.delay += obj.record.delay
  43. obj.index += obj.direction
  44. #if obj.index > (obj.record.spriteSheet.cols - 1) or obj.index < 0:
  45. if not(obj.index in 0..(obj.record.spriteSheet.cols - 1)):
  46. case obj.style
  47. of AnimOnce:
  48. return false
  49. of AnimBounce:
  50. obj.direction *= -1
  51. obj.index += obj.direction * 2
  52. of AnimLoop:
  53. obj.index = 0
  54. obj.spriteRect.left = obj.index.cint * obj.record.spriteSheet.frameW.cint
  55. obj.sprite.setTextureRect obj.spriteRect
  56. proc setPos*(obj: PAnimation; pos: TVector) =
  57. setPosition(obj.sprite, pos.floor())
  58. proc setPos*(obj: PAnimation; pos: TVector2f) =
  59. setPosition(obj.sprite, pos)
  60. proc setAngle*(obj: PAnimation; radians: float) =
  61. let rads = (radians + obj.record.angle).wmod(TAU)
  62. if obj.record.spriteSheet.rows > 1:
  63. ## (rotation percent * rows).floor * frameheight
  64. obj.spriteRect.top = (rads / TAU * obj.record.spriteSheet.rows.float).floor.cint * obj.record.spriteSheet.frameh.cint
  65. obj.sprite.setTextureRect obj.spriteRect
  66. else:
  67. setRotation(obj.sprite, degrees(rads)) #stupid sfml, who uses degrees these days? -__-
  68. proc draw*(window: PRenderWindow; obj: PAnimation) {.inline.} =
  69. window.draw(obj.sprite)