To what I know there is no direct way how to do it.
Sprite solution can be to add Polygon2D as child node of a sprite and mark with it non-alpha part of your sprite. Then you can attach the following script toPolygon2D node. Then you can test whether a point (Vector2D) lies inside the polygon with has_point(point) function. It uses the Ray casting algorithm.
Solution for CollisionObject2D is similar. Instead of adding Polygon2D you can use coordinates of collision object polygon.
extends Polygon2D
var poly_corners = 0 # how many corners the polygon has (no repeats)
var poly_x = [] # horizontal coordinates of corners
var poly_y = [] # vertical coordinates of corners
var constant = [] # storage for precalculated constants (same size as poly_x)
var multiple = [] # storage for precalculated multipliers (same size as poly_x)
var vertices_pos = [] # storage for global coordinates of polygon's vertices
func _ready():
inic()
func inic():
var poly_pos = get_global_pos() # global position of polygon
var vertices = get_polygon() # local coordiantes of vertices
poly_corners = vertices.size()
poly_x.resize(poly_corners)
poly_y.resize(poly_corners)
constant.resize(poly_corners)
multiple.resize(poly_corners)
vertices_pos.resize(poly_corners)
for i in range(poly_corners):
vertices_pos[i] = poly_pos + vertices[i]
poly_x[i] = vertices_pos[i].x
poly_y[i] = vertices_pos[i].y
precalc_values_has_point(poly_x, poly_y)
func precalc_values_has_point(poly_x, poly_y): # precalculation of constant and multiple
var j = poly_corners - 1
for i in range(poly_corners):
if poly_y[j] == poly_x[i]:
constant[i] = poly_y[i]
multiple[i] = 0.0
else:
constant[i] = poly_x[i] - poly_y[i] * poly_x[j] / (poly_y[j] - poly_y[i]) + poly_y[i] * poly_x[i] / (poly_y[j] - poly_y[i])
multiple[i] = (poly_x[j] - poly_x[i]) / (poly_y[j] - poly_y[i])
j = i
func has_point(point):
var x = point.x
var y = point.y
var j = poly_corners - 1
var odd_nodes = 0
for i in range(poly_corners):
if (poly_y[i] < y and poly_y[j] >= y) or (poly_y[j] < y and poly_y[i] >= y):
if y * multiple[i] + constant[i] < x:
odd_nodes += 1
j = i
if odd_nodes % 2 == 0:
return false
else:
return true
The way I finally used was to use
Physics2DDirectSpaceState’s intersect_point method and look at the results.
var space = get_world_2d().get_direct_space_state()
var results = space.intersect_point( thePoint, 32, [], 2147483647, Physics2DDirectSpaceState.TYPE_MASK_AREA )
# then see if the CollisionObject2D is inside the results