kinematic_body2d.nim 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. # author: Ethosa
  2. ## This uses for create hero with physics.
  3. import
  4. ../thirdparty/opengl,
  5. ../core/vector2,
  6. ../core/rect2,
  7. ../core/anchor,
  8. ../core/input,
  9. ../core/enums,
  10. ../nodes/node,
  11. node2d,
  12. collision_shape2d
  13. type
  14. KinematicBody2DObj* = object of Node2DObj
  15. has_collision*: bool
  16. collision_node*: CollisionShape2DPtr
  17. KinematicBody2DPtr* = ptr KinematicBody2DObj
  18. proc KinematicBody2D*(name: string, variable: var KinematicBody2DObj): KinematicBody2DPtr =
  19. ## Creates a new KinematicBody2D pointer.
  20. ##
  21. ## Arguments:
  22. ## - `name` is a node name.
  23. ## - `variable` is a KinematicBody2DObj variable.
  24. runnableExamples:
  25. var
  26. node_obj: KinematicBody2DObj
  27. node = KinematicBody2D("KinematicBody2D", node_obj)
  28. nodepattern(KinematicBody2DObj)
  29. node2dpattern()
  30. variable.has_collision = false
  31. variable.kind = KINEMATIC_BODY_2D_NODE
  32. proc KinematicBody2D*(obj: var KinematicBody2DObj): KinematicBody2DPtr {.inline.} =
  33. ## Creates a new KinematicBody2D pointer with deffault node name "KinematicBody2D".
  34. ##
  35. ## Arguments:
  36. ## - `variable` is a KinematicBody2DObj variable.
  37. runnableExamples:
  38. var
  39. node_obj: KinematicBody2DObj
  40. node = KinematicBody2D(node_obj)
  41. KinematicBody2D("KinematicBody2D", obj)
  42. method addChild*(self: KinematicBody2DPtr, other: CollisionShape2DPtr) {.base.} =
  43. ## Adss collision to the KinematicBody2D.
  44. ## This method should be called one time.
  45. self.children.add(other)
  46. other.parent = self
  47. self.has_collision = true
  48. self.collision_node = other
  49. method getCollideCount*(self: KinematicBody2DPtr): int {.base.} =
  50. ## Checks collision count.
  51. result = 0
  52. if self.has_collision:
  53. var scene = self.getRootNode()
  54. self.calcGlobalPosition()
  55. self.collision_node.calcGlobalPosition()
  56. for node in scene.getChildIter():
  57. if node.kind == COLLISION_SHAPE_2D_NODE:
  58. if node == self.collision_node:
  59. continue
  60. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  61. inc result
  62. method draw*(self: KinematicBody2DPtr, w, h: GLfloat) =
  63. ## this method uses in the `window.nim`.
  64. {.warning[LockLevel]: off.}
  65. self.position = self.timed_position
  66. if self.centered:
  67. self.position = self.timed_position - self.rect_size*2
  68. else:
  69. self.position = self.timed_position
  70. method duplicate*(self: KinematicBody2DPtr, obj: var KinematicBody2DObj): KinematicBody2DPtr {.base.} =
  71. ## Duplicates KinematicBody2D and create a new KinematicBody2D pointer.
  72. obj = self[]
  73. obj.addr
  74. method isCollide*(self: KinematicBody2DPtr): bool {.base.} =
  75. ## Checks any collision and return `true`, when collide with any collision shape.
  76. result = false
  77. if self.has_collision:
  78. var scene = self.getRootNode()
  79. self.calcGlobalPosition()
  80. self.collision_node.calcGlobalPosition()
  81. for node in scene.getChildIter():
  82. if node.kind == COLLISION_SHAPE_2D_NODE:
  83. if node == self.collision_node:
  84. continue
  85. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  86. result = true
  87. break
  88. method moveAndCollide*(self: KinematicBody2DPtr, vel: Vector2Ref) {.base.} =
  89. ## Moves and checks collision
  90. ##
  91. ## Arguments:
  92. ## - `vel` is a velocity vector.
  93. if self.has_collision:
  94. var scene = self.getRootNode()
  95. self.move(vel)
  96. self.calcGlobalPosition()
  97. self.collision_node.calcGlobalPosition()
  98. for node in scene.getChildIter():
  99. if node.kind == COLLISION_SHAPE_2D_NODE:
  100. if node == self.collision_node:
  101. continue
  102. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  103. self.move(-vel.x, 0)
  104. self.calcGlobalPosition()
  105. self.collision_node.calcGlobalPosition()
  106. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  107. self.move(vel.x, -vel.y)
  108. self.calcGlobalPosition()
  109. self.collision_node.calcGlobalPosition()
  110. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  111. self.move(-vel.x, 0)
  112. self.calcGlobalPosition()
  113. self.collision_node.calcGlobalPosition()