1
0

power_up.gd 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. class_name PowerUp
  2. extends RigidBody2D
  3. ## A small token that falls from the top. Catch it with the paddle to collect it.
  4. ## Emitted from a physics callback; connect it deferred before adding or resizing bodies.
  5. signal collected(kind: Kind)
  6. enum Kind {
  7. TRIPLE_BALLS, PADDLE, SUPERBALL,
  8. SLOW, CATCH, SHIELD, BIG_BALL, FIREBALL, RUSH, LASER, FREEZE, BOMB, HOMING,
  9. }
  10. const RADIUS := 12.0
  11. const GLYPH_SIZE := 18
  12. const FONT := preload("res://assets/fonts/abel.ttf")
  13. ## Per kind: name, colour, the letter on the token, first level it drops at, and its weight
  14. ## in the random pick. Triple balls are not in the pick: they drop when the ball is idle.
  15. ## Power-downs (down = true) get likelier as the levels go up.
  16. const KINDS := {
  17. Kind.TRIPLE_BALLS: { name = "Triple balls", color = Params.COLOR_PINK, glyph = "3", unlock = 0, weight = 0.0 },
  18. Kind.PADDLE: { name = "Paddle size", color = Params.COLOR_BLUE, glyph = "P", unlock = 0, weight = 1.0 },
  19. Kind.SUPERBALL: { name = "Super ball", color = Params.COLOR_ORANGE, glyph = "X", unlock = 0, weight = 0.6 },
  20. Kind.SLOW: { name = "Slow-mo", color = Color("#5fb3ff"), glyph = "Z", unlock = 2, weight = 0.8 },
  21. Kind.CATCH: { name = "Catch", color = Color("#8be28b"), glyph = "C", unlock = 4, weight = 0.8 },
  22. Kind.SHIELD: { name = "Shield", color = Color("#f4f4f0"), glyph = "U", unlock = 6, weight = 0.7 },
  23. Kind.BIG_BALL: { name = "Big ball", color = Color("#c9c9c9"), glyph = "O", unlock = 8, weight = 0.7 },
  24. Kind.FIREBALL: { name = "Fireball", color = Params.COLOR_FIRE, glyph = "F", unlock = 12, weight = 0.6 },
  25. Kind.RUSH: { name = "Rush", color = Params.COLOR_PINK, glyph = "!", unlock = 15, weight = 0.4, down = true },
  26. Kind.LASER: { name = "Laser", color = Params.COLOR_RED, glyph = "L", unlock = 20, weight = 0.6 },
  27. Kind.FREEZE: { name = "Freeze", color = Color("#d6f3ff"), glyph = "*", unlock = 25, weight = 0.6 },
  28. Kind.BOMB: { name = "Bomb ball", color = Params.COLOR_BOMB, glyph = "B", unlock = 30, weight = 0.6 },
  29. Kind.HOMING: { name = "Homing", color = Color("#ff8a8a"), glyph = "H", unlock = 40, weight = 0.5 },
  30. }
  31. var kind := Kind.PADDLE
  32. func _ready() -> void:
  33. add_to_group("power_ups")
  34. body_entered.connect(_on_body_entered)
  35. ## Weight of [param kind] in the random pick at [param level]; 0 when not unlocked yet.
  36. static func weight(kind: Kind, level: int) -> float:
  37. var info: Dictionary = KINDS[kind]
  38. if level < info.unlock:
  39. return 0.0
  40. if info.get("down", false):
  41. return info.weight * Params.power_down_factor(level)
  42. return info.weight
  43. func _on_body_entered(body: Node) -> void:
  44. if body is Paddle:
  45. collected.emit(kind)
  46. queue_free()
  47. elif body.is_in_group("bottom"):
  48. queue_free()
  49. func _draw() -> void:
  50. var color: Color = KINDS[kind].color
  51. draw_circle(Vector2.ZERO, RADIUS, color, true, -1.0, true)
  52. # Dark letters on light tokens, light letters on dark ones.
  53. var ink := Params.COLOR_BACK if color.get_luminance() > 0.5 else Color.WHITE
  54. var text: String = KINDS[kind].glyph
  55. var text_size := FONT.get_string_size(text, HORIZONTAL_ALIGNMENT_LEFT, -1, GLYPH_SIZE)
  56. draw_string(FONT, Vector2(-text_size.x / 2.0, FONT.get_ascent(GLYPH_SIZE) / 2.0 - 1.0), text,
  57. HORIZONTAL_ALIGNMENT_LEFT, -1, GLYPH_SIZE, ink)