test_collision_pairs.gd 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. extends Test
  2. const OPTION_TYPE_RECTANGLE = "Collision type/Rectangle (1)"
  3. const OPTION_TYPE_SPHERE = "Collision type/Sphere (2)"
  4. const OPTION_TYPE_CAPSULE = "Collision type/Capsule (3)"
  5. const OPTION_TYPE_CONVEX_POLYGON = "Collision type/Convex Polygon (4)"
  6. const OPTION_TYPE_CONCAVE_SEGMENTS = "Collision type/Concave Segments (5)"
  7. const OPTION_SHAPE_RECTANGLE = "Shape type/Rectangle"
  8. const OPTION_SHAPE_SPHERE = "Shape type/Sphere"
  9. const OPTION_SHAPE_CAPSULE = "Shape type/Capsule"
  10. const OPTION_SHAPE_CONVEX_POLYGON = "Shape type/Convex Polygon"
  11. const OPTION_SHAPE_CONCAVE_POLYGON = "Shape type/Concave Polygon"
  12. const OPTION_SHAPE_CONCAVE_SEGMENTS = "Shape type/Concave Segments"
  13. const OFFSET_RANGE = 120.0
  14. export(Vector2) var offset = Vector2.ZERO
  15. onready var options = $Options
  16. var _update_collision = false
  17. var _collision_test_index = 0
  18. var _current_offset = Vector2.ZERO
  19. var _collision_shapes = []
  20. func _ready():
  21. _initialize_collision_shapes()
  22. options.add_menu_item(OPTION_TYPE_RECTANGLE)
  23. options.add_menu_item(OPTION_TYPE_SPHERE)
  24. options.add_menu_item(OPTION_TYPE_CAPSULE)
  25. options.add_menu_item(OPTION_TYPE_CONVEX_POLYGON)
  26. options.add_menu_item(OPTION_TYPE_CONCAVE_SEGMENTS)
  27. options.add_menu_item(OPTION_SHAPE_RECTANGLE, true, true)
  28. options.add_menu_item(OPTION_SHAPE_SPHERE, true, true)
  29. options.add_menu_item(OPTION_SHAPE_CAPSULE, true, true)
  30. options.add_menu_item(OPTION_SHAPE_CONVEX_POLYGON, true, true)
  31. options.add_menu_item(OPTION_SHAPE_CONCAVE_POLYGON, true, true)
  32. options.add_menu_item(OPTION_SHAPE_CONCAVE_SEGMENTS, true, true)
  33. options.connect("option_selected", self, "_on_option_selected")
  34. options.connect("option_changed", self, "_on_option_changed")
  35. yield(start_timer(0.5), "timeout")
  36. if is_timer_canceled():
  37. return
  38. _update_collision = true
  39. func _input(event):
  40. var key_event = event as InputEventKey
  41. if key_event and not key_event.pressed:
  42. if key_event.scancode == KEY_1:
  43. _on_option_selected(OPTION_TYPE_RECTANGLE)
  44. elif key_event.scancode == KEY_2:
  45. _on_option_selected(OPTION_TYPE_SPHERE)
  46. elif key_event.scancode == KEY_3:
  47. _on_option_selected(OPTION_TYPE_CAPSULE)
  48. elif key_event.scancode == KEY_4:
  49. _on_option_selected(OPTION_TYPE_CONVEX_POLYGON)
  50. elif key_event.scancode == KEY_5:
  51. _on_option_selected(OPTION_TYPE_CONCAVE_SEGMENTS)
  52. func _physics_process(_delta):
  53. if not _update_collision:
  54. return
  55. _update_collision = false
  56. _do_collision_test()
  57. func set_h_offset(value):
  58. offset.x = value * OFFSET_RANGE
  59. _update_collision = true
  60. func set_v_offset(value):
  61. offset.y = -value * OFFSET_RANGE
  62. _update_collision = true
  63. func _initialize_collision_shapes():
  64. _collision_shapes.clear()
  65. for node in $Shapes.get_children():
  66. var body = node as PhysicsBody2D
  67. var shape = body.shape_owner_get_shape(0, 0)
  68. shape.resource_name = String(node.name).substr("RigidBody".length())
  69. _collision_shapes.push_back(shape)
  70. func _do_collision_test():
  71. clear_drawn_nodes()
  72. var shape = _collision_shapes[_collision_test_index]
  73. Log.print_log("* Start %s collision tests..." % shape.resource_name)
  74. var shape_query = Physics2DShapeQueryParameters.new()
  75. shape_query.set_shape(shape)
  76. var shape_scale = Vector2(0.5, 0.5)
  77. shape_query.transform = Transform2D.IDENTITY.scaled(shape_scale)
  78. for node in $Shapes.get_children():
  79. if not node.visible:
  80. continue
  81. var body = node as PhysicsBody2D
  82. var space_state = body.get_world_2d().direct_space_state
  83. Log.print_log("* Testing: %s" % body.name)
  84. var center = body.position
  85. # Collision at the center inside.
  86. var res = _add_collision(space_state, center, shape, shape_query)
  87. Log.print_log("Collision center inside: %s" % ("NO HIT" if res.empty() else "HIT"))
  88. Log.print_log("* Done.")
  89. func _add_collision(space_state, pos, shape, shape_query):
  90. shape_query.transform.origin = pos + offset
  91. var results = space_state.collide_shape(shape_query)
  92. var color
  93. if results.empty():
  94. color = Color.white.darkened(0.5)
  95. else:
  96. color = Color.green
  97. # Draw collision query shape.
  98. add_shape(shape, shape_query.transform, color)
  99. # Draw contact positions.
  100. for contact_pos in results:
  101. add_circle(contact_pos, 1.0, Color.red)
  102. return results
  103. func _on_option_selected(option):
  104. match option:
  105. OPTION_TYPE_RECTANGLE:
  106. _collision_test_index = _find_type_index("Rectangle")
  107. _update_collision = true
  108. OPTION_TYPE_SPHERE:
  109. _collision_test_index = _find_type_index("Sphere")
  110. _update_collision = true
  111. OPTION_TYPE_CAPSULE:
  112. _collision_test_index = _find_type_index("Capsule")
  113. _update_collision = true
  114. OPTION_TYPE_CONVEX_POLYGON:
  115. _collision_test_index = _find_type_index("ConvexPolygon")
  116. _update_collision = true
  117. OPTION_TYPE_CONCAVE_SEGMENTS:
  118. _collision_test_index = _find_type_index("ConcaveSegments")
  119. _update_collision = true
  120. func _find_type_index(type_name):
  121. for type_index in range(_collision_shapes.size()):
  122. var type_shape = _collision_shapes[type_index]
  123. if type_shape.resource_name.find(type_name) > -1:
  124. return type_index
  125. Log.print_error("Invalid collision type: " + type_name)
  126. return -1
  127. func _on_option_changed(option, checked):
  128. var node
  129. match option:
  130. OPTION_SHAPE_RECTANGLE:
  131. node = _find_shape_node("Rectangle")
  132. OPTION_SHAPE_SPHERE:
  133. node = _find_shape_node("Sphere")
  134. OPTION_SHAPE_CAPSULE:
  135. node = _find_shape_node("Capsule")
  136. OPTION_SHAPE_CONVEX_POLYGON:
  137. node = _find_shape_node("ConvexPolygon")
  138. OPTION_SHAPE_CONCAVE_POLYGON:
  139. node = _find_shape_node("ConcavePolygon")
  140. OPTION_SHAPE_CONCAVE_SEGMENTS:
  141. node = _find_shape_node("ConcaveSegments")
  142. if node:
  143. node.visible = checked
  144. node.get_child(0).disabled = not checked
  145. _update_collision = true
  146. func _find_shape_node(type_name):
  147. var node = $Shapes.find_node("RigidBody%s" % type_name)
  148. if not node:
  149. Log.print_error("Invalid shape type: " + type_name)
  150. return node