camera2d.nim 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. # author: Ethosa
  2. import
  3. ../thirdparty/opengl,
  4. ../core/vector2,
  5. ../core/rect2,
  6. ../core/anchor,
  7. ../core/input,
  8. ../core/enums,
  9. ../nodes/node,
  10. ../nodes/canvas,
  11. node2d
  12. type
  13. Camera2DObj* = object of Node2DObj
  14. smooth*: bool
  15. smooth_speed*: float
  16. target*: NodeRef
  17. limit*: AnchorObj ## left, top, right, bottom
  18. Camera2DRef* = ref Camera2DObj
  19. var current_camera: Camera2DRef = nil
  20. proc Camera2D*(name: string = "Camera2D"): Camera2DRef =
  21. ## Creates a new Camera2D.
  22. ##
  23. ## Arguments:
  24. ## - `name` is a node name.
  25. runnableExamples:
  26. var node = Camera2D("Camera2D")
  27. nodepattern(Camera2DRef)
  28. node2dpattern()
  29. result.limit = Anchor(-100000, -100000, 100000, 100000)
  30. result.smooth = false
  31. result.smooth_speed = 0.1
  32. result.kind = CAMERA_2D_NODE
  33. method changeTarget*(self: Camera2DRef, target: NodeRef) {.base.} =
  34. ## Changes camera target (without camera position.)
  35. self.target = target
  36. method changeSmoothSpeed*(self: Camera2DRef, speed: float) {.base.} =
  37. ## Changes camera smooth speed.
  38. ##
  39. ## Arguments:
  40. ## - `speed` is a smooth speed. The closer to 0, the smoother the camera. The default is 0.1.
  41. self.smooth_speed = speed
  42. method disableSmooth*(self: Camera2DRef) {.base.} =
  43. ## Disables smooth mode.
  44. ##
  45. ## See also:
  46. ## - `enableSmooth method <#enableSmooth.e,Camera2DRef,float>`_
  47. self.smooth = false
  48. method draw*(self: Camera2DRef, w, h: GLfloat) =
  49. ## this method uses in the `window.nim`.
  50. {.warning[LockLevel]: off.}
  51. procCall self.Node2DRef.draw(w, h)
  52. if self.target != nil and self == current_camera:
  53. var root = self.getRootNode().CanvasRef
  54. let
  55. x = self.target.CanvasRef.position.x
  56. y = self.target.CanvasRef.position.y
  57. if self.smooth:
  58. if x-w/2 > self.limit.x1 and x+w/2 < self.limit.x2:
  59. let dx = (root.position.x - w/2) + x
  60. root.position.x -= dx*self.smooth_speed
  61. if y-h/2 > self.limit.y1 and y+h/2 < self.limit.y2:
  62. let dy = (root.position.y - h/2) + y
  63. root.position.y -= dy*self.smooth_speed
  64. else:
  65. root.position.x = if x-w/2 < self.limit.x1: root.position.x elif x+w/2 > self.limit.x2: root.position.x else: -(x - w/2)
  66. root.position.y = if y+h/2 < self.limit.y1: root.position.y elif y+h/2 > self.limit.y2: root.position.y else: -(y - h/2)
  67. method duplicate*(self: Camera2DRef): Camera2DRef {.base.} =
  68. ## Duplicates Camera2D and create a new Camera2D object.
  69. self.deepCopy()
  70. method enableSmooth*(self: Camera2DRef, speed: float = 0.1) {.base.} =
  71. ## Enables camera smooth mode.
  72. ##
  73. ## Arguments:
  74. ## - `speed` is a smooth speed. The closer to 0, the smoother the camera. The default is 0.1.
  75. ##
  76. ## See also:
  77. ## - `disableSmooth method <#disableSmooth.e,Camera2DRef>`_
  78. self.smooth = true
  79. self.smooth_speed = speed
  80. method isCurrent*(self: Camera2DRef): bool {.base.} =
  81. self == current_camera
  82. method setCurrent*(self: Camera2DRef) {.base.} =
  83. ## Changes the current camera. It also automatically disable other cameras.
  84. current_camera = self
  85. method setLimit*(self: Camera2DRef, x1, y1, x2, y2: float) {.base.} =
  86. ## Change camera limit.
  87. self.limit = Anchor(x1, y1, x2, y2)
  88. method setLimit*(self: Camera2DRef, limit: AnchorObj) {.base.} =
  89. ## Changes camera limit.
  90. self.limit = limit
  91. method setTarget*(self: Camera2DRef, target: NodeRef) {.base.} =
  92. ## Changes camera target node.
  93. self.target = target
  94. var root = self.getRootNode().CanvasRef
  95. self.CanvasRef.position = target.CanvasRef.global_position
  96. self.CanvasRef.position -= root.rect_size / 2