diff --git a/scenes/objects/GiftBox.tscn b/scenes/objects/GiftBox.tscn new file mode 100644 index 0000000..e30f919 --- /dev/null +++ b/scenes/objects/GiftBox.tscn @@ -0,0 +1,47 @@ +[gd_scene load_steps=2 format=3 uid="uid://cozypaw_giftbox"] + +[ext_resource type="Script" path="res://scripts/objects/gift_box.gd" id="1_giftbox"] + +[node name="GiftBox" type="Node2D"] +script = ExtResource("1_giftbox") + +[node name="BoxBase" type="ColorRect" parent="."] +offset_left = -40.0 +offset_top = -60.0 +offset_right = 40.0 +offset_bottom = 0.0 +color = Color(0.90, 0.28, 0.34, 1) + +[node name="BoxStripe" type="ColorRect" parent="."] +offset_left = -6.0 +offset_top = -60.0 +offset_right = 6.0 +offset_bottom = 0.0 +color = Color(0.98, 0.82, 0.22, 1) + +[node name="Lid" type="Node2D" parent="."] +position = Vector2(0, -60) + +[node name="LidShape" type="ColorRect" parent="Lid"] +offset_left = -44.0 +offset_top = -18.0 +offset_right = 44.0 +offset_bottom = 0.0 +color = Color(0.98, 0.38, 0.42, 1) + +[node name="LidBow" type="ColorRect" parent="Lid"] +offset_left = -10.0 +offset_top = -28.0 +offset_right = 10.0 +offset_bottom = -18.0 +color = Color(0.98, 0.82, 0.22, 1) + +[node name="Gift" type="Node2D" parent="."] +position = Vector2(0, -90) + +[node name="GiftShape" type="ColorRect" parent="Gift"] +offset_left = -20.0 +offset_top = -20.0 +offset_right = 20.0 +offset_bottom = 20.0 +color = Color(0.96, 0.76, 0.22, 1) diff --git a/scripts/objects/gift_box.gd b/scripts/objects/gift_box.gd new file mode 100644 index 0000000..c84cd99 --- /dev/null +++ b/scripts/objects/gift_box.gd @@ -0,0 +1,55 @@ +## GiftBox — tap while closed to open: lid rises and fades out, gift inside fades in. +class_name GiftBox extends Node2D + +enum State { CLOSED, OPENING, OPEN } + +const LID_OPEN_Y: float = -120.0 +const OPEN_DURATION: float = 0.5 +const GIFT_FADE_DURATION: float = 0.4 +const BUTTON_HALF_WIDTH: float = 40.0 +const BUTTON_HALF_HEIGHT: float = 50.0 + +var _state: State = State.CLOSED + + +func _ready() -> void: + var gift: Node2D = get_node_or_null("Gift") as Node2D + if gift != null: + gift.modulate.a = 0.0 + + +func _input(event: InputEvent) -> void: + if _state != State.CLOSED: + return + if not event is InputEventScreenTouch: + return + var touch: InputEventScreenTouch = event as InputEventScreenTouch + if not touch.pressed: + return + var local: Vector2 = to_local(touch.position) + if abs(local.x) > BUTTON_HALF_WIDTH or abs(local.y) > BUTTON_HALF_HEIGHT: + return + _start_opening() + + +func _start_opening() -> void: + _state = State.OPENING + var lid: Node2D = get_node_or_null("Lid") as Node2D + if lid == null: + _state = State.OPEN + return + var tween: Tween = create_tween() + tween.set_ease(Tween.EASE_OUT) + tween.set_trans(Tween.TRANS_BACK) + tween.tween_property(lid, "position:y", LID_OPEN_Y, OPEN_DURATION) + tween.parallel().tween_property(lid, "modulate:a", 0.0, OPEN_DURATION) + tween.finished.connect(_on_lid_opened) + + +func _on_lid_opened() -> void: + _state = State.OPEN + 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)