blocks.gd 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. class_name Blocks
  2. extends Node2D
  3. ## The core plus rings of rotating blocks around it, generated from the level number.
  4. const SEGMENTS_PER_RING := 10
  5. const MAX_RING_SPEED := 30.0 # degrees per second
  6. var core: Core
  7. var _rings: Array[Node2D] = []
  8. var _speeds: Array[float] = []
  9. func build(level: int) -> void:
  10. var layout := _layout(level)
  11. for index in range(layout.rings - 1, -1, -1):
  12. _add_ring(layout.size, index, layout.indestructible_chance)
  13. core = Core.new()
  14. add_child(core)
  15. func _physics_process(delta: float) -> void:
  16. for i in _rings.size():
  17. _rings[i].rotation_degrees += _speeds[i] * delta
  18. ## Ring count, ring thickness and indestructible-block chance for a level. Each level adds
  19. ## a ring or raises the chance; once there are too many rings they restart thinner.
  20. ## Ported as-is from BlocksLayer::setLevel.
  21. static func _layout(level: int) -> Dictionary:
  22. var count := 0
  23. var delta := 15
  24. var size := Params.CORE_RADIUS * 0.75
  25. var rings := 1
  26. var chance := 0.0
  27. var i := 0
  28. while count <= level:
  29. var j := 0
  30. while count <= level and j <= i:
  31. if i + 1 > delta:
  32. delta = int(delta * 1.5)
  33. size /= 1.5
  34. i = 0
  35. rings = i + 1
  36. chance = j * 0.05 / delta * 8.0
  37. count += 1
  38. j += 1
  39. i += 1
  40. return { rings = rings, size = size, indestructible_chance = chance }
  41. func _add_ring(size: float, index: int, indestructible_chance: float) -> void:
  42. var inner := index * size + Params.CORE_RADIUS
  43. var outer := (index + 1) * size + Params.CORE_RADIUS
  44. # Evenly spaced segment boundaries, each jittered so segments have uneven lengths.
  45. var step := TAU / SEGMENTS_PER_RING
  46. var bounds: Array[float] = []
  47. for i in SEGMENTS_PER_RING:
  48. bounds.append(step * i + randf_range(-1.0, 1.0) * 0.45 * step)
  49. bounds.append(bounds[0] + TAU)
  50. var ring := Node2D.new()
  51. for i in SEGMENTS_PER_RING:
  52. var indestructible := indestructible_chance >= randf()
  53. ring.add_child(Block.new(inner, outer, bounds[i], bounds[i + 1], indestructible))
  54. add_child(ring)
  55. _rings.append(ring)
  56. _speeds.append(randf_range(-MAX_RING_SPEED, MAX_RING_SPEED))