class_name Blocks extends Node2D ## The core plus rings of rotating blocks around it, generated from the level number. const SEGMENTS_PER_RING := 10 const MAX_RING_SPEED := 30.0 # degrees per second var core: Core var _rings: Array[Node2D] = [] var _speeds: Array[float] = [] func build(level: int) -> void: var layout := _layout(level) for index in range(layout.rings - 1, -1, -1): _add_ring(layout.size, index, layout.indestructible_chance) core = Core.new() add_child(core) func _physics_process(delta: float) -> void: for i in _rings.size(): _rings[i].rotation_degrees += _speeds[i] * delta ## Ring count, ring thickness and indestructible-block chance for a level. Each level adds ## a ring or raises the chance; once there are too many rings they restart thinner. ## Ported as-is from BlocksLayer::setLevel. static func _layout(level: int) -> Dictionary: var count := 0 var delta := 15 var size := Params.CORE_RADIUS * 0.75 var rings := 1 var chance := 0.0 var i := 0 while count <= level: var j := 0 while count <= level and j <= i: if i + 1 > delta: delta = int(delta * 1.5) size /= 1.5 i = 0 rings = i + 1 chance = j * 0.05 / delta * 8.0 count += 1 j += 1 i += 1 return { rings = rings, size = size, indestructible_chance = chance } func _add_ring(size: float, index: int, indestructible_chance: float) -> void: var inner := index * size + Params.CORE_RADIUS var outer := (index + 1) * size + Params.CORE_RADIUS # Evenly spaced segment boundaries, each jittered so segments have uneven lengths. var step := TAU / SEGMENTS_PER_RING var bounds: Array[float] = [] for i in SEGMENTS_PER_RING: bounds.append(step * i + randf_range(-1.0, 1.0) * 0.45 * step) bounds.append(bounds[0] + TAU) var ring := Node2D.new() for i in SEGMENTS_PER_RING: var indestructible := indestructible_chance >= randf() ring.add_child(Block.new(inner, outer, bounds[i], bounds[i + 1], indestructible)) add_child(ring) _rings.append(ring) _speeds.append(randf_range(-MAX_RING_SPEED, MAX_RING_SPEED))