diff --git a/scenes/component_spawn.gd b/scenes/component_spawn.gd index b6e88cf..a71b6bb 100644 --- a/scenes/component_spawn.gd +++ b/scenes/component_spawn.gd @@ -7,7 +7,7 @@ var _active_walkers: Array[Node] = [] var _batch_generation: int = 0 @onready var survivor = preload("res://scenes/survivor.tscn") -@onready var survivor_spawn = get_node("/root/Game/World/SuvivorSpawn") +@onready var survivor_spawn = get_node("/root/Game/World/SurvivorSpawn") @onready var start_pos: Vector3 = survivor_spawn.global_position func _enter_tree() -> void: @@ -38,6 +38,6 @@ func _run_batch(count: int, generation: int) -> void: func _spawn_one() -> void: var s = survivor.instantiate() var offset := Vector3(randf_range(-lateral_variance, lateral_variance), 0, 0) - get_tree().root.add_child.call_deferred(s) + add_child.call_deferred(s) s.position = start_pos + offset _active_walkers.append(s) diff --git a/scenes/elevator.gd b/scenes/elevator.gd index c46f635..0a113a2 100644 --- a/scenes/elevator.gd +++ b/scenes/elevator.gd @@ -11,23 +11,32 @@ var _tween: Tween = null func _ready(): $ElevatorDoorRight.position = Vector3(DOOR_CLOSED_X, 0, 0) $ElevatorDoorLeft.position = Vector3(-DOOR_CLOSED_X, 0, 0) + _set_door_collision(true) EventBus.doors_opened.connect(_on_doors_opened) EventBus.doors_closed.connect(_on_doors_closed) EventBus.pulse_started.connect(_on_pulse_started) EventBus.pulse_blocked.connect(_on_pulse_blocked) func _on_doors_opened(): + _set_door_collision(false) _tween_doors(DOOR_OPEN_X, DOOR_DEFAULT_TIME) func _on_doors_closed(fast: bool): + _set_door_collision(true) _tween_doors(DOOR_CLOSED_X, DOOR_FAST_CLOSE_TIME if fast else DOOR_DEFAULT_TIME) func _on_pulse_started(duration: float): + _set_door_collision(true) _tween_doors(DOOR_CLOSED_X, duration) func _on_pulse_blocked(): + _set_door_collision(false) _tween_doors(DOOR_OPEN_X, DOOR_REOPEN_TIME) +func _set_door_collision(enabled: bool): + $ElevatorDoorRight/CollisionShape3D.disabled = not enabled + $ElevatorDoorLeft/CollisionShape3D.disabled = not enabled + func _tween_doors(target_x: float, duration: float): if _tween: _tween.kill() diff --git a/scenes/elevator_panel.gd b/scenes/elevator_panel.gd index 7a3f491..121041a 100644 --- a/scenes/elevator_panel.gd +++ b/scenes/elevator_panel.gd @@ -1,6 +1,9 @@ extends PanelContainer -var current_floor := 10 +@onready var _screen = $PanelMargin/PanelColumn/Screen +@onready var _close_button: Button = $PanelMargin/PanelColumn/CloseButton + +var current_floor: int = EventBus.STARTING_FLOOR var saved_count := 0 var doors_closing_flag := false var _onboarded := false @@ -30,15 +33,13 @@ const PERFECT_STUN_DURATION := 0.25 const PRE_PULSE_DELAY := 3.5 func _ready(): - var button = $PanelMargin/PanelColumn/CloseButton - button.text = "CLOSE" - button.pressed.connect(_on_block_pressed) + _close_button.text = "CLOSE" + _close_button.pressed.connect(_on_block_pressed) - var screen = $PanelMargin/PanelColumn/Screen - screen.pulse_started.connect(_on_pulse_started) - screen.pulse_blocked.connect(_on_pulse_blocked) - screen.pulse_blocked_perfect.connect(_on_pulse_blocked_perfect) - screen.doors_closing.connect(func(): _on_doors_closing(true)) + _screen.pulse_started.connect(_on_pulse_started) + _screen.pulse_blocked.connect(_on_pulse_blocked) + _screen.pulse_blocked_perfect.connect(_on_pulse_blocked_perfect) + _screen.doors_closing.connect(func(): _on_doors_closing(true)) EventBus.game_started.connect(_start_floor) @@ -54,7 +55,7 @@ func _start_floor(): $SfxBell.play() doors_closing_flag = false people_in_elevator = 0 - $PanelMargin/PanelColumn/CloseButton.text = "CLOSE" + _close_button.text = "CLOSE" EventBus.doors_opened.emit() var floors_remaining = current_floor - 1 @@ -64,27 +65,26 @@ func _start_floor(): EventBus.floor_changed.emit(current_floor) EventBus.floor_started.emit(survivors_remaining) - var floors_descended = 10 - current_floor + var floors_descended = EventBus.STARTING_FLOOR - current_floor var robot_speed = robot_speed_top + floors_descended * robot_speed_per_floor var robot_delay = max(robot_delay_min, robot_delay_top - floors_descended * robot_delay_per_floor) EventBus.robot_floor_started.emit(robot_delay, robot_speed) - var screen = $PanelMargin/PanelColumn/Screen - screen.start(current_floor) + _screen.start(current_floor) if current_floor <= MOVING_ZONE_START_FLOOR: var floors_below = MOVING_ZONE_START_FLOOR - current_floor - screen.set_block_zone_movement(MOVING_ZONE_BASE_SPEED + floors_below * MOVING_ZONE_SPEED_PER_FLOOR) + _screen.set_block_zone_movement(MOVING_ZONE_BASE_SPEED + floors_below * MOVING_ZONE_SPEED_PER_FLOOR) if not _onboarded: _onboarded = true - screen.show_onboarding("BLOCK\nIN GREEN ZONE") + _screen.show_onboarding("BLOCK\nIN GREEN ZONE") get_tree().create_timer(3.0).timeout.connect( func(): - if not is_instance_valid(screen): + if not is_instance_valid(_screen): return - screen.end_onboarding() - screen.launch_pulse(), + _screen.end_onboarding() + _screen.launch_pulse(), CONNECT_ONE_SHOT ) else: @@ -92,28 +92,27 @@ func _start_floor(): func(): if not is_instance_valid(self) or doors_closing_flag: return - screen.launch_pulse(), + _screen.launch_pulse(), CONNECT_ONE_SHOT ) func _on_block_pressed(): if doors_closing_flag: return - var screen = $PanelMargin/PanelColumn/Screen - if screen.pulse_active: - screen.attempt_block() + if _screen.pulse_active: + _screen.attempt_block() else: _on_doors_closing(false) func _on_pulse_started(duration: float): - $PanelMargin/PanelColumn/CloseButton.text = "BLOCK" + _close_button.text = "BLOCK" EventBus.pulse_started.emit(duration) func _on_pulse_blocked_perfect(): EventBus.robot_stun_requested.emit(PERFECT_STUN_DURATION) func _on_pulse_blocked(): - $PanelMargin/PanelColumn/CloseButton.text = "CLOSE" + _close_button.text = "CLOSE" EventBus.pulse_blocked.emit() survivors_remaining -= 1 people_in_elevator += 1 @@ -124,12 +123,11 @@ func _on_pulse_blocked(): get_tree().create_timer(0.25).timeout.connect(_on_doors_closing, CONNECT_ONE_SHOT) return - var screen = $PanelMargin/PanelColumn/Screen - var gap = screen.get_pulse_gap() + var gap = _screen.get_pulse_gap() get_tree().create_timer(gap).timeout.connect( func(): if not doors_closing_flag: - screen.launch_pulse(), + _screen.launch_pulse(), CONNECT_ONE_SHOT ) @@ -139,10 +137,8 @@ func _on_doors_closing(fast: bool = false): doors_closing_flag = true EventBus.doors_closed.emit(fast) - var screen = $PanelMargin/PanelColumn/Screen - if people_in_elevator < threshold: - screen.show_loss("TOO FEW") + _screen.show_loss("TOO FEW") EventBus.game_lost.emit("TOO FEW") return @@ -157,14 +153,14 @@ func _on_doors_closing(fast: bool = false): current_floor -= 1 if current_floor <= 1: - screen.show_win() + _screen.show_win() EventBus.floor_changed.emit(current_floor) EventBus.game_won.emit() return $SfxClose.play() - screen.show_countdown() - screen.shrink_block_zone() + _screen.show_countdown() + _screen.shrink_block_zone() var tween = create_tween() tween.tween_interval(3.0) diff --git a/scenes/elevator_panel.tscn b/scenes/elevator_panel.tscn index d7237a4..08e7f0d 100644 --- a/scenes/elevator_panel.tscn +++ b/scenes/elevator_panel.tscn @@ -11,12 +11,15 @@ corner_radius_bottom_right = 4 corner_radius_bottom_left = 4 [node name="ElevatorPanel" type="PanelContainer" unique_id=574176994] -custom_minimum_size = Vector2(250, 0) -anchors_preset = 11 +anchors_preset = 6 anchor_left = 1.0 +anchor_top = 0.5 anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = -8.0 +anchor_bottom = 0.5 +offset_left = -200.0 +offset_top = -140.0 +offset_right = -10.0 +offset_bottom = 140.0 grow_horizontal = 0 grow_vertical = 2 script = ExtResource("1_1gr6t") @@ -32,7 +35,7 @@ theme_override_constants/margin_bottom = 15 layout_mode = 2 [node name="Screen" type="Panel" parent="PanelMargin/PanelColumn" unique_id=1395085208] -custom_minimum_size = Vector2(200, 200) +custom_minimum_size = Vector2(160, 160) layout_mode = 2 theme_override_styles/panel = SubResource("StyleBoxFlat_n2snw") script = ExtResource("1_3gei6") diff --git a/scenes/hud.gd b/scenes/hud.gd index 1467967..479a866 100644 --- a/scenes/hud.gd +++ b/scenes/hud.gd @@ -23,14 +23,7 @@ func update_floor(floor_num: int): _displayed_floor = floor_num return _displayed_floor = floor_num - label.pivot_offset = Vector2(0, label.size.y) - var tween = create_tween() - tween.tween_property(label, "scale:y", 0.0, 0.15).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN) - tween.tween_callback(func(): - label.text = new_text - label.pivot_offset = Vector2.ZERO - ) - tween.tween_property(label, "scale:y", 1.0, 0.15).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) + UIUtils.flip_label_text(label, new_text) func update_saved(count: int): $StatsColumn/SavedLabel.text = "SAVED: " + str(count) diff --git a/scenes/pause_menu.gd b/scenes/pause_menu.gd index b3259d7..0aaac74 100644 --- a/scenes/pause_menu.gd +++ b/scenes/pause_menu.gd @@ -4,10 +4,9 @@ var _enabled := false func _ready(): visible = false - EventBus.game_started.connect(_on_game_started) - -func _on_game_started(): - _enabled = true + EventBus.game_started.connect(func(): _enabled = true) + EventBus.game_won.connect(func(): _enabled = false) + EventBus.game_lost.connect(func(_reason: String): _enabled = false) func _unhandled_input(event): if not _enabled: diff --git a/scenes/screen.gd b/scenes/screen.gd index 3e7c63e..59330f2 100644 --- a/scenes/screen.gd +++ b/scenes/screen.gd @@ -40,6 +40,7 @@ var _glow: ColorRect var _perfect_zone: ColorRect var _face_scale_tween: Tween var _face_shake_tween: Tween +var _flash_tween: Tween var _floor_label: Label signal pulse_started(duration: float) @@ -99,10 +100,10 @@ func _ready(): add_child(_floor_label) EventBus.floor_changed.connect(_update_floor_label) -func start(floor_num: int = 10): +func start(floor_num: int = EventBus.STARTING_FLOOR): active = true pulses_blocked = 0 - var floors_descended = 10 - floor_num + var floors_descended = EventBus.STARTING_FLOOR - floor_num pulse_speed = pulse_speed_initial + floors_descended * pulse_speed_per_floor pulse_gap = 1.0 $AIFace.text = ">:)" @@ -148,14 +149,7 @@ func _update_floor_label(floor_num: int): _displayed_floor = floor_num return _displayed_floor = floor_num - _floor_label.pivot_offset = Vector2(0, _floor_label.size.y) - var tween = create_tween() - tween.tween_property(_floor_label, "scale:y", 0.0, 0.15).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN) - tween.tween_callback(func(): - _floor_label.text = new_text - _floor_label.pivot_offset = Vector2.ZERO - ) - tween.tween_property(_floor_label, "scale:y", 1.0, 0.15).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) + UIUtils.flip_label_text(_floor_label, new_text) func _update_perfect_zone(): var bz = $TargetZone @@ -252,9 +246,11 @@ func flash(color: Color): var style = get_theme_stylebox("panel") as StyleBoxFlat if not style: return + if _flash_tween: + _flash_tween.kill() style.bg_color = color - var tween = create_tween() - tween.tween_property(style, "bg_color", base_color, 0.3) + _flash_tween = create_tween() + _flash_tween.tween_property(style, "bg_color", base_color, 0.3) func show_countdown(): stop() diff --git a/scenes/survivor.gd b/scenes/survivor.gd index 5b40d05..5906960 100644 --- a/scenes/survivor.gd +++ b/scenes/survivor.gd @@ -9,6 +9,7 @@ static var _last_chase: AudioStream = null var speed: int = 3 var clumsiness: int = 0 +var _saved: bool = false @onready var safety_zone = get_node("/root/Game/World/ElevatorSafeZone") @@ -28,12 +29,14 @@ func _ready(): CONNECT_ONE_SHOT ) -func _physics_process(delta): - velocity.z -= speed * delta +func _physics_process(_delta): + velocity.z = -speed move_and_slide() func _on_area_3d_area_entered(area: Area3D) -> void: - var safety = safety_zone - if area == safety: - print("Safe!") - queue_free() + if area == safety_zone and not _saved: + _saved = true + get_tree().create_timer(0.5).timeout.connect( + func(): queue_free(), + CONNECT_ONE_SHOT + ) diff --git a/scenes/world.tscn b/scenes/world.tscn index 76f6b6b..397049b 100644 --- a/scenes/world.tscn +++ b/scenes/world.tscn @@ -43,7 +43,7 @@ transform = Transform3D(4, 0, 0, 0, 4, 0, 0, 0, 4, 0, 3, 0) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.8164063, -0.30373383) shape = SubResource("BoxShape3D_k0juu") -[node name="SuvivorSpawn" type="Marker3D" parent="." unique_id=1095768768] +[node name="SurvivorSpawn" type="Marker3D" parent="." unique_id=1095768768] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.9181392, 13.711893) gizmo_extents = 1.46 diff --git a/scripts/event_bus.gd b/scripts/event_bus.gd index a3866f0..c726fc2 100644 --- a/scripts/event_bus.gd +++ b/scripts/event_bus.gd @@ -1,5 +1,7 @@ extends Node +const STARTING_FLOOR := 10 + @warning_ignore_start("unused_signal") signal floor_changed(floor_num: int) diff --git a/scripts/ui_utils.gd b/scripts/ui_utils.gd new file mode 100644 index 0000000..552eaf7 --- /dev/null +++ b/scripts/ui_utils.gd @@ -0,0 +1,11 @@ +class_name UIUtils + +static func flip_label_text(label: Label, new_text: String, duration: float = 0.15) -> void: + label.pivot_offset = Vector2(0, label.size.y) + var tween = label.create_tween() + tween.tween_property(label, "scale:y", 0.0, duration).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_IN) + tween.tween_callback(func(): + label.text = new_text + label.pivot_offset = Vector2.ZERO + ) + tween.tween_property(label, "scale:y", 1.0, duration).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT) diff --git a/scripts/ui_utils.gd.uid b/scripts/ui_utils.gd.uid new file mode 100644 index 0000000..fa0ec0b --- /dev/null +++ b/scripts/ui_utils.gd.uid @@ -0,0 +1 @@ +uid://bp4uktnrbpag8