| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- extends Node2D
- ## Title screen: the big core with turning rings and bouncing balls, the player's progress,
- ## what unlocks next, and a music toggle.
- const BALL_SCENE := preload("res://scenes/ball.tscn")
- const BALLS := 6
- const RING_SPEEDS := [12.0, -8.0] # degrees per second, one per decorative ring
- ## Kinds sprinkled into the decorative rings, as a taste of what is coming.
- const SHOWCASE := [
- Block.Kind.INDESTRUCTIBLE, Block.Kind.WATER, Block.Kind.ICE, Block.Kind.TNT,
- Block.Kind.RUBBER, Block.Kind.MOSS,
- ]
- var _level := 0
- var _rings: Array[Node2D] = []
- @onready var core: Core = $Core
- func _ready() -> void:
- var screen := get_viewport_rect().size
- core.position = Vector2(screen.x / 2.0, screen.y * 0.28)
- _add_rings()
- for i in BALLS:
- var ball: Ball = BALL_SCENE.instantiate()
- ball.position = Vector2(screen.x / 2.0, screen.y - Params.BALL_RADIUS * 2.0)
- $Balls.add_child(ball)
- ball.throw()
- var progress := Progress.load_level()
- _level = progress[0]
- $UI/Info/Level.text = "Level %d" % _level
- $UI/Info/Totals/Count.text = str(Progress.total_stars())
- var best := Progress.best_score()
- $UI/Info/Best.text = "Best score %d" % best if best > 0 else ""
- $UI/Play.text = "Play" if _level == 0 else "Continue"
- $UI/Next.text = _next_unlock(_level)
- if _level != 0:
- $UI/Decay.text = Params.MSG_LEVEL_BACK % [_level, progress[1]]
- $UI/Play.pressed.connect(_on_play_pressed)
- $UI/MusicToggle.pressed.connect(_on_music_toggled)
- _show_music_state()
- Music.play("menu")
- func _physics_process(delta: float) -> void:
- for i in _rings.size():
- _rings[i].rotation_degrees += RING_SPEEDS[i] * delta
- ## Two thin rings of segments around the core, mostly normal with a few special kinds.
- ## They are only decoration: no collisions.
- func _add_rings() -> void:
- var inner := core.radius + 6.0
- for r in RING_SPEEDS.size():
- var ring := Node2D.new()
- ring.position = core.position
- var segments := 12 + r * 4
- var step := TAU / segments
- for i in segments:
- var kind: Block.Kind = SHOWCASE[(i + r * 3) % SHOWCASE.size()] if i % 3 == 0 else Block.Kind.NORMAL
- var block := Block.new(inner + r * 30.0, inner + r * 30.0 + 26.0, i * step, (i + 1) * step, kind)
- block.collision_layer = 0
- block.set_physics_process(false)
- ring.add_child(block)
- add_child(ring)
- move_child(ring, core.get_index())
- _rings.append(ring)
- ## "Next: Fireball at level 12" for the next power or segment to unlock after [param level].
- static func _next_unlock(level: int) -> String:
- var best_level := -1
- var best_name := ""
- for info: Dictionary in PowerUp.KINDS.values() + Block.KINDS.values():
- var unlock: int = info.unlock
- if unlock > level and (best_level < 0 or unlock < best_level):
- best_level = unlock
- best_name = info.name
- if best_level < 0:
- return "Everything unlocked. How far can you go?"
- return "Next: %s at level %d" % [best_name, best_level]
- func _on_play_pressed() -> void:
- Progress.current_level = _level
- get_tree().change_scene_to_file("res://scenes/game.tscn")
- func _on_music_toggled() -> void:
- Music.set_enabled(not Progress.music_on())
- _show_music_state()
- func _show_music_state() -> void:
- $UI/MusicToggle.text = "Music: %s" % ("on" if Progress.music_on() else "off")
|