From 164d0f76be95c4dec888d953b698f45720abcaa0 Mon Sep 17 00:00:00 2001 From: Jennie Robinson Faber Date: Fri, 8 May 2026 21:38:53 +0100 Subject: [PATCH] Add HUD scene with elevator hack timing minigame - elevator panel w/ a screen and close button - screen.gd timing minigame: sweep line bounces across a shrinking target zone - hud wiring to move down floors on successful hacks, countdown/win states, and speed up AI on misses --- hud.gd | 41 ++++++++++++++++++++ hud.gd.uid | 1 + hud.tscn | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ project.godot | 1 + screen.gd | 99 ++++++++++++++++++++++++++++++++++++++++++++++++ screen.gd.uid | 1 + 6 files changed, 245 insertions(+) create mode 100644 hud.gd create mode 100644 hud.gd.uid create mode 100644 hud.tscn create mode 100644 screen.gd create mode 100644 screen.gd.uid diff --git a/hud.gd b/hud.gd new file mode 100644 index 0000000..81c1b64 --- /dev/null +++ b/hud.gd @@ -0,0 +1,41 @@ +extends Control + +# I HAVE NO IDEA WHAT I'M DOIN!!! +var current_floor := 10 +var saved_count := 0 + +var doors_closing := false + + +func _ready(): + $ElevatorPanel/PanelMargin/PanelColumn/CloseButton.pressed.connect(_on_close_pressed) + # 10 floors is probably a lot but will make testing easier. + $StatsMargin/StatsColumn/FloorLabel.text = "FLOOR: 10" + +func _unhandled_input(event): + if event is InputEventKey and event.pressed and event.keycode == KEY_SPACE: + _on_close_pressed() + +func _on_close_pressed(): + # don't let 'em spam the button + if doors_closing: + return + var screen = $ElevatorPanel/PanelMargin/PanelColumn/Screen + var success = screen.attempt_hack() + if success: + doors_closing = true + saved_count += 1 + current_floor -= 1 + $StatsMargin/StatsColumn/SavedLabel.text = "SAVED: " + str(saved_count) + $StatsMargin/StatsColumn/FloorLabel.text = "FLOOR: " + str(current_floor) + if current_floor <= 1: + screen.show_win() + else: + screen.show_countdown() + var tween = create_tween() + tween.tween_callback(func(): + screen.reset_hack() + doors_closing = false + ).set_delay(2.0) + else: + print("MISSED! AI is faster now!") diff --git a/hud.gd.uid b/hud.gd.uid new file mode 100644 index 0000000..7a2ab16 --- /dev/null +++ b/hud.gd.uid @@ -0,0 +1 @@ +uid://k1n4iyxp4iww diff --git a/hud.tscn b/hud.tscn new file mode 100644 index 0000000..f12bb28 --- /dev/null +++ b/hud.tscn @@ -0,0 +1,102 @@ +[gd_scene format=3 uid="uid://d4j36ro8y55ep"] + +[ext_resource type="Script" uid="uid://kltqwef8yx3r" path="res://screen.gd" id="1_37p78"] +[ext_resource type="Script" uid="uid://k1n4iyxp4iww" path="res://hud.gd" id="1_64ctp"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_n2snw"] +bg_color = Color(0.039215688, 0.16470589, 0.039215688, 1) +corner_radius_top_left = 4 +corner_radius_top_right = 4 +corner_radius_bottom_right = 4 +corner_radius_bottom_left = 4 + +[node name="HUD" type="Control" unique_id=1519812318] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_64ctp") + +[node name="StatsMargin" type="MarginContainer" parent="." unique_id=428486326] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 + +[node name="StatsColumn" type="VBoxContainer" parent="StatsMargin" unique_id=365054136] +layout_mode = 2 + +[node name="PeopleLabel" type="Label" parent="StatsMargin/StatsColumn" unique_id=203661849] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "PEOPLE: 0" + +[node name="SavedLabel" type="Label" parent="StatsMargin/StatsColumn" unique_id=830917509] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "SAVED: 0" + +[node name="FloorLabel" type="Label" parent="StatsMargin/StatsColumn" unique_id=320822205] +layout_mode = 2 +theme_override_font_sizes/font_size = 24 +text = "FLOOR: 0" + +[node name="ElevatorPanel" type="PanelContainer" parent="." unique_id=528786554] +custom_minimum_size = Vector2(250, 0) +layout_mode = 1 +anchors_preset = 11 +anchor_left = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -8.0 +grow_horizontal = 0 +grow_vertical = 2 + +[node name="PanelMargin" type="MarginContainer" parent="ElevatorPanel" unique_id=277992523] +layout_mode = 2 +theme_override_constants/margin_left = 15 +theme_override_constants/margin_top = 15 +theme_override_constants/margin_right = 15 +theme_override_constants/margin_bottom = 15 + +[node name="PanelColumn" type="VBoxContainer" parent="ElevatorPanel/PanelMargin" unique_id=617812367] +layout_mode = 2 + +[node name="Screen" type="Panel" parent="ElevatorPanel/PanelMargin/PanelColumn" unique_id=1525784323] +custom_minimum_size = Vector2(200, 200) +layout_mode = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_n2snw") +script = ExtResource("1_37p78") + +[node name="TargetZone" type="ColorRect" parent="ElevatorPanel/PanelMargin/PanelColumn/Screen" unique_id=1945539908] +custom_minimum_size = Vector2(40, 160) +layout_mode = 0 +offset_left = 88.0 +offset_top = 18.0 +offset_right = 128.0 +offset_bottom = 178.0 +color = Color(0.101960786, 0.3529412, 0.101960786, 1) + +[node name="SweepLine" type="ColorRect" parent="ElevatorPanel/PanelMargin/PanelColumn/Screen" unique_id=1798423613] +custom_minimum_size = Vector2(4, 160) +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 40.0 +color = Color(1, 0, 0, 1) + +[node name="AIFace" type="Label" parent="ElevatorPanel/PanelMargin/PanelColumn/Screen" unique_id=1410806030] +layout_mode = 0 +offset_right = 40.0 +offset_bottom = 23.0 +theme_override_colors/font_color = Color(0.2, 1, 0.2, 1) +theme_override_font_sizes/font_size = 32 +text = ">:)" + +[node name="CloseButton" type="Button" parent="ElevatorPanel/PanelMargin/PanelColumn" unique_id=427545014] +custom_minimum_size = Vector2(0, 60) +layout_mode = 2 +theme_override_font_sizes/font_size = 28 +text = "CLOSE" diff --git a/project.godot b/project.godot index 3c0f7a2..ecc2b8b 100644 --- a/project.godot +++ b/project.godot @@ -11,6 +11,7 @@ config_version=5 [application] config/name="tojam20-elevator" +run/main_scene="uid://d4j36ro8y55ep" config/features=PackedStringArray("4.6", "Forward Plus") config/icon="res://icon.svg" diff --git a/screen.gd b/screen.gd new file mode 100644 index 0000000..fd25409 --- /dev/null +++ b/screen.gd @@ -0,0 +1,99 @@ +extends Panel + +var sweep_speed := 150.0 +var sweep_direction := 1 +var sweep_x := 0.0 +var is_hacked := true + +var style_box: StyleBoxFlat +var base_color: Color + +var target_shrink := 4.0 +var target_min_width := 8.0 + +signal hack_defeated +signal hack_failed + +func _ready(): + style_box = get_theme_stylebox("panel").duplicate() + add_theme_stylebox_override("panel", style_box) + base_color = style_box.bg_color + + var tz = $TargetZone + tz.position = Vector2((size.x - tz.size.x) / 2, 20) + tz.size = Vector2(40, size.y - 40) + + var sl = $SweepLine + sl.position = Vector2(0, 20) + sl.size = Vector2(4, size.y - 40) + sweep_x = 0.0 + + var face = $AIFace + face.position = Vector2(0, 0) + face.size = Vector2(size.x, 30) + face.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + +func _process(delta): + if not is_hacked: + return + + sweep_x += sweep_speed * sweep_direction * delta + + if sweep_x >= size.x: + sweep_direction = -1 + elif sweep_x <= 0: + sweep_direction = 1 + + $SweepLine.position.x = sweep_x + +func flash(color: Color): + style_box.bg_color = color + var tween = create_tween() + tween.tween_property(style_box, "bg_color", base_color, 0.3) + +func reset_hack(): + is_hacked = true + sweep_x = 0.0 + sweep_direction = 1 + $SweepLine.visible = true + $SweepLine.position.x = 0 + $AIFace.text = ">:)" + + var tz = $TargetZone + tz.size.x = max(tz.size.x - target_shrink, target_min_width) + tz.position.x = (size.x - tz.size.x) / 2 + +# messtastic +func show_countdown(): + var tween = create_tween() + $AIFace.text = "3" + tween.tween_callback(func(): $AIFace.text = "2").set_delay(0.6) + tween.tween_callback(func(): $AIFace.text = "1").set_delay(0.6) + tween.tween_callback(func(): $AIFace.text = "CLOSED").set_delay(0.6) + +func show_win(): + is_hacked = false + $SweepLine.visible = false + $TargetZone.visible = false + $AIFace.text = "ESCAPED" + flash(Color.GREEN) + +# target zones +func attempt_hack() -> bool: + var tz = $TargetZone + var tz_left = tz.position.x + var tz_right = tz.position.x + tz.size.x + + if sweep_x >= tz_left and sweep_x <= tz_right: + is_hacked = false + $AIFace.text = ">:(" + $SweepLine.visible = false + flash(Color.GREEN) + hack_defeated.emit() + return true + else: + sweep_speed += 20.0 + $AIFace.text = ":D" + flash(Color.RED) + hack_failed.emit() + return false diff --git a/screen.gd.uid b/screen.gd.uid new file mode 100644 index 0000000..fc5dbba --- /dev/null +++ b/screen.gd.uid @@ -0,0 +1 @@ +uid://kltqwef8yx3r