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