From 05a06b455a87db14020518c40f7c06c259cc7cac Mon Sep 17 00:00:00 2001 From: Sara Date: Thu, 30 Oct 2025 23:50:32 +0100 Subject: [PATCH] feat: implemented victim file animation and popup --- flatscreen-project/scenes/workspace.tscn | 68 ++++++++++++++++++- modules/you_done_it/file_popup.cpp | 84 ++++++++++++++++++++++++ modules/you_done_it/file_popup.h | 28 ++++++++ modules/you_done_it/register_types.cpp | 2 + 4 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 modules/you_done_it/file_popup.cpp create mode 100644 modules/you_done_it/file_popup.h diff --git a/flatscreen-project/scenes/workspace.tscn b/flatscreen-project/scenes/workspace.tscn index 95c20339..994dc840 100644 --- a/flatscreen-project/scenes/workspace.tscn +++ b/flatscreen-project/scenes/workspace.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=7 format=3 uid="uid://o3ri154wpbrx"] +[gd_scene load_steps=13 format=3 uid="uid://o3ri154wpbrx"] [ext_resource type="PackedScene" uid="uid://btcmnw6q6g0h0" path="res://objects/pinned_photo.tscn" id="1_7cefc"] @@ -17,6 +17,36 @@ size = Vector2(1074, 533) [sub_resource type="RectangleShape2D" id="RectangleShape2D_7cefc"] size = Vector2(295, 346) +[sub_resource type="QuadMesh" id="QuadMesh_7cefc"] + +[sub_resource type="GDScript" id="GDScript_7cefc"] +script/source = "extends Area2D + + +func _on_input_event(viewport: Node, event: InputEvent, _shape_idx: int) -> void: + if event is InputEventMouseButton: + if not $\"..\".is_open(): + $\"..\".request_open() + else: + $\"..\".request_close() + viewport.set_input_as_handled() +" + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_vo7lu"] +size = Vector2(52.031464, 209.99301) + +[sub_resource type="TextMesh" id="TextMesh_7cefc"] +flip_faces = true +text = "Victim" +depth = 0.0 + +[sub_resource type="Gradient" id="Gradient_vo7lu"] +offsets = PackedFloat32Array(1) +colors = PackedColorArray(0, 0, 0, 1) + +[sub_resource type="GradientTexture1D" id="GradientTexture1D_wjago"] +gradient = SubResource("Gradient_vo7lu") + [node name="FlatscreenRoot" type="Node2D"] [node name="Camera2D" type="Camera2D" parent="."] @@ -51,3 +81,39 @@ offset_left = 1604.0 offset_top = 181.0 offset_right = 1822.0 offset_bottom = 346.0 + +[node name="FilePopup" type="FilePopup" parent="." node_paths=PackedStringArray("open_position")] +position = Vector2(12.000002, 0) +rotation = 0.08145886 +open_position = NodePath("../FilePositionTarget") + +[node name="MeshInstance2D2" type="MeshInstance2D" parent="FilePopup"] +position = Vector2(22.500002, 142.6643) +scale = Vector2(77, 222.67134) +mesh = SubResource("QuadMesh_7cefc") + +[node name="MeshInstance2D" type="MeshInstance2D" parent="FilePopup"] +position = Vector2(-333.25, 486.25) +scale = Vector2(667.5, 973.5) +mesh = SubResource("QuadMesh_7cefc") + +[node name="Area2D" type="Area2D" parent="FilePopup"] +position = Vector2(29.17066, 143.39133) +script = SubResource("GDScript_7cefc") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="FilePopup/Area2D"] +scale = Vector2(1.0000002, 1.0000002) +shape = SubResource("RectangleShape2D_vo7lu") + +[node name="MeshInstance2D3" type="MeshInstance2D" parent="FilePopup"] +position = Vector2(33.037315, 137.30455) +rotation = 1.5707964 +scale = Vector2(-347.0554, 307.87436) +mesh = SubResource("TextMesh_7cefc") +texture = SubResource("GradientTexture1D_wjago") + +[node name="FilePositionTarget" type="Node2D" parent="."] +position = Vector2(593, 40.000004) +rotation = 0.24976808 + +[connection signal="input_event" from="FilePopup/Area2D" to="FilePopup/Area2D" method="_on_input_event"] diff --git a/modules/you_done_it/file_popup.cpp b/modules/you_done_it/file_popup.cpp new file mode 100644 index 00000000..4d140104 --- /dev/null +++ b/modules/you_done_it/file_popup.cpp @@ -0,0 +1,84 @@ +#include "file_popup.h" +#include "core/config/engine.h" +#include "core/input/input_event.h" +#include "core/math/math_funcs.h" +#include "scene/main/node.h" +#include "scene/main/viewport.h" +#include "you_done_it/macros.h" + +void FilePopup::_bind_methods() { + BIND_HPROPERTY(Variant::OBJECT, open_position, PROPERTY_HINT_NODE_TYPE, "Node2D"); + ClassDB::bind_method(D_METHOD("request_open"), &self_type::request_open); + ClassDB::bind_method(D_METHOD("request_close"), &self_type::request_close); + ClassDB::bind_method(D_METHOD("is_open"), &self_type::is_open); +} + +void FilePopup::enter_tree() { + this->home_position = get_global_transform(); +} + +void FilePopup::process(double delta) { + if (!this->open_position) { + set_process(false); + return; + } + this->animation_progress = Math::move_toward(this->animation_progress, this->desire_open ? 1.0 : 0.0, delta * this->ANIM_SPEED); + this->set_global_position(this->home_position.get_origin().lerp(this->open_position->get_global_position(), this->animation_progress)); + this->set_global_rotation(Math::lerp_angle(this->home_position.get_rotation(), this->open_position->get_global_rotation(), (float)this->animation_progress)); + if (this->animation_progress == 0.0) { + set_process(false); + set_process_unhandled_input(false); + } + if (this->animation_progress == 1.0) { + set_process(false); + } +} + +void FilePopup::unhandled_input(Ref const &what) { + Ref button{ what }; + if (button.is_valid() && button->is_pressed()) { + this->desire_open = false; + set_process(true); + get_viewport()->set_input_as_handled(); + } +} + +void FilePopup::_notification(int what) { + if (Engine::get_singleton()->is_editor_hint()) { + return; + } + switch (what) { + default: + return; + case NOTIFICATION_ENTER_TREE: + set_process_unhandled_input(true); + enter_tree(); + return; + case NOTIFICATION_PROCESS: + process(get_process_delta_time()); + return; + } +} + +void FilePopup::request_open() { + this->desire_open = true; + set_process_unhandled_input(true); + set_process(true); + set_visible(true); +} + +void FilePopup::request_close() { + this->desire_open = false; +} + +bool FilePopup::is_open() const { + return this->animation_progress == 1.0; +} + +void FilePopup::set_open_position(Node2D *node) { + this->open_position = node; +} + +Node2D *FilePopup::get_open_position() const { + return this->open_position; +} diff --git a/modules/you_done_it/file_popup.h b/modules/you_done_it/file_popup.h new file mode 100644 index 00000000..e71ce019 --- /dev/null +++ b/modules/you_done_it/file_popup.h @@ -0,0 +1,28 @@ +#pragma once + +#include "scene/2d/node_2d.h" + +class FilePopup : public Node2D { + GDCLASS(FilePopup, Node2D); + static void _bind_methods(); + void enter_tree(); + void process(double delta); + +protected: + virtual void unhandled_input(Ref const &what) override; + void _notification(int what); + +public: + void request_open(); + void request_close(); + bool is_open() const; + void set_open_position(Node2D *node); + Node2D *get_open_position() const; + +private: + double animation_progress{ 0.0 }; + bool desire_open{ false }; + Transform2D home_position{}; + Node2D *open_position{ nullptr }; + double const ANIM_SPEED{ 3.0 }; +}; diff --git a/modules/you_done_it/register_types.cpp b/modules/you_done_it/register_types.cpp index e203bfba..c82312a7 100644 --- a/modules/you_done_it/register_types.cpp +++ b/modules/you_done_it/register_types.cpp @@ -5,6 +5,7 @@ #include "you_done_it/clue_data.h" #include "you_done_it/clue_finder.h" #include "you_done_it/clue_marker.h" +#include "you_done_it/file_popup.h" #include "you_done_it/photo_inbox.h" #include "you_done_it/pinboard.h" #include "you_done_it/pinned_photo.h" @@ -27,6 +28,7 @@ void initialize_you_done_it_module(ModuleInitializationLevel p_level) { ClassDB::register_class(); ClassDB::register_class(); ClassDB::register_class(); + ClassDB::register_class(); } void uninitialize_you_done_it_module(ModuleInitializationLevel p_level) {