diff --git a/scripts/objects/gift_box.gd b/scripts/objects/gift_box.gd index d76ba80..98cbdf8 100644 --- a/scripts/objects/gift_box.gd +++ b/scripts/objects/gift_box.gd @@ -1,11 +1,14 @@ ## GiftBox — tap while closed to open: lid rises and fades out, gift inside fades in. +## Auto-resets after RESET_DELAY seconds. class_name GiftBox extends Node2D -enum State { CLOSED, OPENING, OPEN } +enum State { CLOSED, OPENING, RESETTING } const LID_OPEN_Y: float = -120.0 +const CLOSED_LID_Y: float = -60.0 const OPEN_DURATION: float = 0.5 const GIFT_FADE_DURATION: float = 0.4 +const RESET_DELAY: float = 3.0 const BUTTON_HALF_WIDTH: float = 40.0 const BUTTON_HALF_HEIGHT: float = 50.0 @@ -37,7 +40,7 @@ func _start_opening() -> void: _state = State.OPENING var lid: Node2D = get_node_or_null("Lid") as Node2D if lid == null: - _state = State.OPEN + _on_lid_opened() return var tween: Tween = create_tween() tween.set_ease(Tween.EASE_OUT) @@ -48,9 +51,26 @@ func _start_opening() -> void: func _on_lid_opened() -> void: - _state = State.OPEN + _state = State.RESETTING var gift: Node2D = get_node_or_null("Gift") as Node2D - if gift == null: - return var tween: Tween = create_tween() - tween.tween_property(gift, "modulate:a", 1.0, GIFT_FADE_DURATION) + if gift != null: + tween.tween_property(gift, "modulate:a", 1.0, GIFT_FADE_DURATION) + tween.tween_interval(RESET_DELAY) + tween.tween_callback(_start_close_lid) + + +func _start_close_lid() -> void: + var lid: Node2D = get_node_or_null("Lid") as Node2D + var gift: Node2D = get_node_or_null("Gift") as Node2D + var tween: Tween = create_tween().set_parallel(true) + if lid != null: + tween.tween_property(lid, "position:y", CLOSED_LID_Y, OPEN_DURATION) + tween.tween_property(lid, "modulate:a", 1.0, OPEN_DURATION) + if gift != null: + tween.tween_property(gift, "modulate:a", 0.0, OPEN_DURATION) + tween.finished.connect(_on_reset_complete) + + +func _on_reset_complete() -> void: + _state = State.CLOSED diff --git a/test/unit/test_gift_box.gd b/test/unit/test_gift_box.gd index e4ca149..07c981e 100644 --- a/test/unit/test_gift_box.gd +++ b/test/unit/test_gift_box.gd @@ -1,4 +1,4 @@ -## Tests for GiftBox — CLOSED/OPENING/OPEN state machine transitions. +## Tests for GiftBox — CLOSED/OPENING/RESETTING state machine transitions. extends GutTest var _box: GiftBox @@ -23,10 +23,10 @@ func test_start_opening_transitions_to_opening() -> void: assert_eq(_box._state, GiftBox.State.OPENING) -func test_on_lid_opened_transitions_to_open() -> void: +func test_on_lid_opened_transitions_to_resetting() -> void: _box._start_opening() _box._on_lid_opened() - assert_eq(_box._state, GiftBox.State.OPEN) + assert_eq(_box._state, GiftBox.State.RESETTING) func test_input_ignored_when_state_is_opening() -> void: @@ -38,13 +38,13 @@ func test_input_ignored_when_state_is_opening() -> void: assert_eq(_box._state, GiftBox.State.OPENING) -func test_input_ignored_when_state_is_open() -> void: - _box._state = GiftBox.State.OPEN +func test_input_ignored_when_state_is_resetting() -> void: + _box._state = GiftBox.State.RESETTING var event: InputEventScreenTouch = InputEventScreenTouch.new() event.pressed = true event.position = _box.global_position _box._input(event) - assert_eq(_box._state, GiftBox.State.OPEN) + assert_eq(_box._state, GiftBox.State.RESETTING) func test_tap_outside_hitbox_does_not_open() -> void: @@ -61,3 +61,9 @@ func test_release_event_does_not_open() -> void: event.position = _box.global_position _box._input(event) assert_eq(_box._state, GiftBox.State.CLOSED) + + +func test_on_reset_complete_transitions_to_closed() -> void: + _box._state = GiftBox.State.RESETTING + _box._on_reset_complete() + assert_eq(_box._state, GiftBox.State.CLOSED)