diff --git a/scenes/objects/Ambulance.tscn b/scenes/objects/Ambulance.tscn new file mode 100644 index 0000000..2f43509 --- /dev/null +++ b/scenes/objects/Ambulance.tscn @@ -0,0 +1,41 @@ +[gd_scene load_steps=2 format=3 uid="uid://cozypaw_ambulance"] + +[ext_resource type="Script" path="res://scripts/objects/ambulance.gd" id="1_ambulance"] + +[node name="Ambulance" type="Node2D"] +script = ExtResource("1_ambulance") + +[node name="Body" type="ColorRect" parent="."] +color = Color(1.0, 1.0, 1.0, 1) +size = Vector2(180, 100) +position = Vector2(-90, -50) + +[node name="RedStripe" type="ColorRect" parent="."] +color = Color(0.90, 0.15, 0.15, 1) +size = Vector2(180, 20) +position = Vector2(-90, -15) + +[node name="Cabin" type="ColorRect" parent="."] +color = Color(0.82, 0.85, 0.90, 1) +size = Vector2(70, 60) +position = Vector2(-90, -50) + +[node name="WindowFront" type="ColorRect" parent="."] +color = Color(0.60, 0.85, 1.0, 1) +size = Vector2(50, 38) +position = Vector2(-82, -46) + +[node name="WheelFront" type="ColorRect" parent="."] +color = Color(0.15, 0.15, 0.15, 1) +size = Vector2(30, 30) +position = Vector2(-75, 48) + +[node name="WheelBack" type="ColorRect" parent="."] +color = Color(0.15, 0.15, 0.15, 1) +size = Vector2(30, 30) +position = Vector2(50, 48) + +[node name="Siren" type="ColorRect" parent="."] +color = Color(0.10, 0.40, 1.0, 1) +size = Vector2(40, 18) +position = Vector2(-20, -68) diff --git a/scripts/objects/ambulance.gd b/scripts/objects/ambulance.gd new file mode 100644 index 0000000..5bb5829 --- /dev/null +++ b/scripts/objects/ambulance.gd @@ -0,0 +1,84 @@ +## Ambulance — drives in from off-screen right when Emergency Room is entered; tap to toggle. +class_name Ambulance extends Node2D + +const OFFSCREEN_OFFSET: float = 1200.0 +const BUTTON_HALF_WIDTH: float = 90.0 +const BUTTON_HALF_HEIGHT: float = 50.0 +const DRIVE_DURATION: float = 1.2 + +@export var trigger_floor: int = 0 +@export var trigger_room: int = 3 + +var _parked_x: float = 0.0 +var _is_parked: bool = false +var _is_animating: bool = false + + +func _ready() -> void: + _parked_x = position.x + position.x = _parked_x + OFFSCREEN_OFFSET + RoomNavigator.room_changed.connect(_on_room_changed) + + +func _exit_tree() -> void: + if RoomNavigator.room_changed.is_connected(_on_room_changed): + RoomNavigator.room_changed.disconnect(_on_room_changed) + + +func _on_room_changed(floor_index: int, room_index: int) -> void: + if floor_index == trigger_floor and room_index == trigger_room: + if not _is_parked and not _is_animating: + _drive_in() + + +func _input(event: InputEvent) -> void: + if _is_animating: + return + var screen_pos: Vector2 + if event is InputEventScreenTouch and event.pressed: + screen_pos = event.position + elif event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: + screen_pos = event.position + else: + return + var canvas_transform: Transform2D = get_viewport().get_canvas_transform() + var world_pos: Vector2 = canvas_transform.affine_inverse() * screen_pos + var local_pos: Vector2 = to_local(world_pos) + if abs(local_pos.x) <= BUTTON_HALF_WIDTH and abs(local_pos.y) <= BUTTON_HALF_HEIGHT: + if _is_parked: + _drive_out() + else: + _drive_in() + + +func _drive_in() -> void: + _is_animating = true + _is_parked = false + var tween: Tween = create_tween() + tween.set_ease(Tween.EASE_OUT) + tween.set_trans(Tween.TRANS_QUAD) + tween.tween_property(self, "position:x", _parked_x, DRIVE_DURATION) + tween.finished.connect(func() -> void: + _is_parked = true + _is_animating = false + _play_stop_bounce() + ) + + +func _drive_out() -> void: + _is_animating = true + _is_parked = false + var tween: Tween = create_tween() + tween.set_ease(Tween.EASE_IN) + tween.set_trans(Tween.TRANS_QUAD) + tween.tween_property(self, "position:x", _parked_x + OFFSCREEN_OFFSET, DRIVE_DURATION) + tween.finished.connect(func() -> void: + _is_animating = false + ) + + +func _play_stop_bounce() -> void: + var tween: Tween = create_tween() + tween.tween_property(self, "scale", Vector2(1.08, 0.94), 0.08) + tween.tween_property(self, "scale", Vector2(0.96, 1.06), 0.08) + tween.tween_property(self, "scale", Vector2(1.0, 1.0), 0.08)