class_name Block extends AnimatableBody2D ## One arc-shaped segment of a ring around the core. var indestructible := false var color := Params.COLOR_BLUE var _polygon := PackedVector2Array() func _init(inner: float, outer: float, begin: float, end: float, is_indestructible: bool) -> void: sync_to_physics = false collision_layer = Params.LAYER_BLOCKS collision_mask = 0 indestructible = is_indestructible # Leave a ~1px gap between neighbouring segments. begin += 1.0 / outer end -= 1.0 / outer var steps := maxi(2, int((end - begin) * sqrt(outer) / 1.5)) var outer_arc := _arc(outer, begin, end, steps) # The drawn shape stops 2px short of the inner radius to leave a gap between rings. _polygon = outer_arc + _arc(inner + 2.0, end, begin, steps) var collision := CollisionPolygon2D.new() collision.polygon = outer_arc + _arc(inner, end, begin, steps) add_child(collision) if indestructible: color = Params.COLOR_ORANGE else: color = Color8( int(102 * (randf() / 5.0 + 0.5)), int(217 * (randf() / 5.0 + 0.5)), int(239 * (randf() / 5.0 + 0.5))) func destroy() -> void: collision_layer = 0 queue_free() func _draw() -> void: draw_colored_polygon(_polygon, color) # Polygons have no antialiasing of their own; a smooth outline softens the edge. var outline := _polygon.duplicate() outline.append(_polygon[0]) draw_polyline(outline, color, 1.0, true) static func _arc(radius: float, from: float, to: float, steps: int) -> PackedVector2Array: var points := PackedVector2Array() for i in steps + 1: var angle := lerpf(from, to, float(i) / steps) points.append(Vector2(sin(angle), cos(angle)) * radius) return points