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