kinematic_body2d.nim 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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.calcGlobalPosition()
  66. self.position = self.timed_position
  67. if self.centered:
  68. self.position = self.timed_position - self.rect_size*2
  69. else:
  70. self.position = self.timed_position
  71. method duplicate*(self: KinematicBody2DPtr, obj: var KinematicBody2DObj): KinematicBody2DPtr {.base.} =
  72. ## Duplicates KinematicBody2D and create a new KinematicBody2D pointer.
  73. obj = self[]
  74. obj.addr
  75. method isCollide*(self: KinematicBody2DPtr): bool {.base.} =
  76. ## Checks any collision and return `true`, when collide with any collision shape.
  77. result = false
  78. if self.has_collision:
  79. var scene = self.getRootNode()
  80. self.calcGlobalPosition()
  81. self.collision_node.calcGlobalPosition()
  82. for node in scene.getChildIter():
  83. if node.kind == COLLISION_SHAPE_2D_NODE:
  84. if node == self.collision_node:
  85. continue
  86. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  87. result = true
  88. break
  89. method moveAndCollide*(self: KinematicBody2DPtr, vel: Vector2Ref) {.base.} =
  90. ## Moves and checks collision
  91. ##
  92. ## Arguments:
  93. ## - `vel` is a velocity vector.
  94. if self.has_collision:
  95. var scene = self.getRootNode()
  96. self.move(vel)
  97. self.calcGlobalPosition()
  98. self.collision_node.calcGlobalPosition()
  99. for node in scene.getChildIter():
  100. if node.kind == COLLISION_SHAPE_2D_NODE:
  101. if node == self.collision_node:
  102. continue
  103. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  104. self.move(-vel.x, 0)
  105. self.calcGlobalPosition()
  106. self.collision_node.calcGlobalPosition()
  107. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  108. self.move(vel.x, -vel.y)
  109. self.calcGlobalPosition()
  110. self.collision_node.calcGlobalPosition()
  111. if self.collision_node.isCollide(node.CollisionShape2DPtr):
  112. self.move(-vel.x, 0)
  113. self.calcGlobalPosition()
  114. self.collision_node.calcGlobalPosition()