Run End Screens
This commit is contained in:
+10
-3
@@ -11,6 +11,10 @@ enum GameState {
|
|||||||
var current_state: GameState = GameState.HUB
|
var current_state: GameState = GameState.HUB
|
||||||
var _previous_state: GameState = GameState.HUB
|
var _previous_state: GameState = GameState.HUB
|
||||||
|
|
||||||
|
const RunEndScreenScene = preload("res://scripts/ui/run_end_screen.gd")
|
||||||
|
|
||||||
|
var _run_end_screen: CanvasLayer = null
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
EventBus.run_started.connect(_on_run_started)
|
EventBus.run_started.connect(_on_run_started)
|
||||||
EventBus.run_ended.connect(_on_run_ended)
|
EventBus.run_ended.connect(_on_run_ended)
|
||||||
@@ -48,7 +52,10 @@ func start_run() -> void:
|
|||||||
func _on_run_started() -> void:
|
func _on_run_started() -> void:
|
||||||
change_state(GameState.RUN)
|
change_state(GameState.RUN)
|
||||||
|
|
||||||
func _on_run_ended(_survived: bool) -> void:
|
func _on_run_ended(reached_hub: bool) -> void:
|
||||||
# Body parts are always kept — save before returning to hub
|
# Save immediately — body parts and bank are always kept
|
||||||
SaveManager.save()
|
SaveManager.save()
|
||||||
call_deferred("go_to_hub")
|
# Show end screen; it calls go_to_hub() when ready
|
||||||
|
_run_end_screen = RunEndScreenScene.new()
|
||||||
|
get_tree().root.add_child(_run_end_screen)
|
||||||
|
_run_end_screen.show_result(reached_hub)
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
extends CanvasLayer
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Run End Screen
|
||||||
|
# Instantiated by GameManager on run_ended. Call show_result(bool) after
|
||||||
|
# adding to tree. Calls GameManager.go_to_hub() when ready.
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const FADE_IN_TIME := 0.3
|
||||||
|
const FADE_OUT_TIME := 0.3
|
||||||
|
const DEATH_HOLD := 2.5
|
||||||
|
|
||||||
|
var _root: Control = null
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
layer = 10
|
||||||
|
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||||
|
|
||||||
|
|
||||||
|
func show_result(reached_hub: bool) -> void:
|
||||||
|
if reached_hub:
|
||||||
|
_show_victory()
|
||||||
|
else:
|
||||||
|
_show_death()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Death screen — auto-advances after DEATH_HOLD seconds
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
func _show_death() -> void:
|
||||||
|
_build_root(Color(0, 0, 0, 0.85))
|
||||||
|
|
||||||
|
_add_label("SYSTEMS OFFLINE", 36, Vector2(0, -80))
|
||||||
|
_add_label("FLOOR %d" % RunManager.current_floor, 20, Vector2(0, 0))
|
||||||
|
_add_label("ALL RUN DATA LOST", 16, Vector2(0, 40))
|
||||||
|
|
||||||
|
_fade_in()
|
||||||
|
await get_tree().create_timer(DEATH_HOLD).timeout
|
||||||
|
_fade_out_then_hub()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Victory screen — player must click to continue
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
func _show_victory() -> void:
|
||||||
|
_build_root(Color(0, 0, 0, 0.75))
|
||||||
|
|
||||||
|
_add_label("RUN COMPLETE", 36, Vector2(0, -100))
|
||||||
|
_add_label("FLOOR %d CLEARED" % RunManager.current_floor, 20, Vector2(0, -40))
|
||||||
|
_add_label("SCRAP RETURNED: %d" % UpgradeManager.wallet_credits, 18, Vector2(0, 10))
|
||||||
|
|
||||||
|
var btn := Button.new()
|
||||||
|
btn.text = "RETURN TO HUB"
|
||||||
|
btn.position = Vector2(-80, 70)
|
||||||
|
btn.pressed.connect(_fade_out_then_hub)
|
||||||
|
_root.add_child(btn)
|
||||||
|
|
||||||
|
_fade_in()
|
||||||
|
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# Helpers
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
func _build_root(bg_color: Color) -> void:
|
||||||
|
if _root:
|
||||||
|
_root.queue_free()
|
||||||
|
|
||||||
|
var bg := ColorRect.new()
|
||||||
|
bg.color = bg_color
|
||||||
|
bg.anchor_right = 1.0
|
||||||
|
bg.anchor_bottom = 1.0
|
||||||
|
bg.mouse_filter = Control.MOUSE_FILTER_STOP
|
||||||
|
add_child(bg)
|
||||||
|
|
||||||
|
_root = Control.new()
|
||||||
|
_root.set_anchors_preset(Control.PRESET_CENTER)
|
||||||
|
bg.add_child(_root)
|
||||||
|
|
||||||
|
|
||||||
|
func _add_label(text: String, font_size: int, offset: Vector2) -> void:
|
||||||
|
var lbl := Label.new()
|
||||||
|
lbl.text = text
|
||||||
|
lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
||||||
|
lbl.add_theme_font_size_override("font_size", font_size)
|
||||||
|
lbl.position = offset + Vector2(-200, 0)
|
||||||
|
lbl.custom_minimum_size = Vector2(400, 0)
|
||||||
|
_root.add_child(lbl)
|
||||||
|
|
||||||
|
|
||||||
|
func _fade_in() -> void:
|
||||||
|
modulate.a = 0.0
|
||||||
|
var tw := create_tween()
|
||||||
|
tw.tween_property(self, "modulate:a", 1.0, FADE_IN_TIME)
|
||||||
|
|
||||||
|
|
||||||
|
func _fade_out_then_hub() -> void:
|
||||||
|
var tw := create_tween()
|
||||||
|
tw.tween_property(self, "modulate:a", 0.0, FADE_OUT_TIME)
|
||||||
|
tw.tween_callback(func(): GameManager.go_to_hub())
|
||||||
Reference in New Issue
Block a user