From eefda9e2bd6c0b2e24a653ab78bf4e6954a3d09e Mon Sep 17 00:00:00 2001 From: Taevas Date: Thu, 27 Mar 2025 16:00:39 +0100 Subject: [PATCH] start creating the framework for menus (#3) all very experimental so it'll see lots of changes --- menus/main/area.tscn | 110 +++++++++++++++++++++++++++++ menus/main/panel.tscn | 113 ++++++++++++++++++++++++++++++ menus/main/save_file_manager.tscn | 102 +++++++++++++++++++++++++++ menus/main/start_menu.tscn | 54 ++++++++++++++ menus/menu.tscn | 99 ++++++++++++++++++++++++++ project.godot | 2 +- 6 files changed, 479 insertions(+), 1 deletion(-) create mode 100644 menus/main/area.tscn create mode 100644 menus/main/panel.tscn create mode 100644 menus/main/save_file_manager.tscn create mode 100644 menus/main/start_menu.tscn create mode 100644 menus/menu.tscn diff --git a/menus/main/area.tscn b/menus/main/area.tscn new file mode 100644 index 0000000..731bf77 --- /dev/null +++ b/menus/main/area.tscn @@ -0,0 +1,110 @@ +[gd_scene load_steps=7 format=3 uid="uid://ikeidrgprk8k"] + +[ext_resource type="PackedScene" uid="uid://wlhsarkeqe8r" path="res://menus/main/panel.tscn" id="1_qfa5o"] + +[sub_resource type="GDScript" id="GDScript_bt14i"] +script/source = "extends Node3D + +var start_menu = preload(\"res://menus/main/start_menu.tscn\") +var save_file_manager = preload(\"res://menus/main/save_file_manager.tscn\") + +func _ready() -> void: + var sm = start_menu.instantiate() + sm.connect(\"request_start\", start) + sm.connect(\"request_settings\", settings) + $Menus/Panel1.change_menu(sm) + +func start() -> void: + var svm = save_file_manager.instantiate() + $Menus/Panel2.change_menu(svm) + rotate_cube(90) + +func settings() -> void: + rotate_cube(90) + +func rotate_cube(degrees: int) -> void: + if $Menus/AnimationPlayer.is_playing(): + return + degrees = -degrees + + var animation: Animation = $Menus/AnimationPlayer.get_animation(\"rotate\") + var new_rotation = $Menus.rotation_degrees + Vector3(0, degrees, 0) + animation.track_set_key_value(0, 0, $Menus.rotation_degrees) + animation.track_set_key_value(0, 1, new_rotation) + + $Menus/AnimationPlayer.play(\"rotate\") +" + +[sub_resource type="Animation" id="Animation_0jxef"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:rotation_degrees") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [Vector3(0, 0, 0)] +} + +[sub_resource type="Animation" id="Animation_bt14i"] +resource_name = "rotate" +length = 0.3 +step = 0.3 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:rotation_degrees") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector3(0, 0, 0), Vector3(0, 0, 0)] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_3bwb0"] +_data = { +&"RESET": SubResource("Animation_0jxef"), +&"rotate": SubResource("Animation_bt14i") +} + +[sub_resource type="Environment" id="Environment_qfa5o"] +background_mode = 1 +background_color = Color(0.804743, 0.804743, 0.804743, 1) + +[node name="Area" type="Node3D"] +process_mode = 3 +script = SubResource("GDScript_bt14i") + +[node name="SpotLight3D" type="SpotLight3D" parent="."] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 1.90692, 0) + +[node name="Menus" type="CSGBox3D" parent="."] + +[node name="Panel1" parent="Menus" instance=ExtResource("1_qfa5o")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0.501) + +[node name="Panel2" parent="Menus" instance=ExtResource("1_qfa5o")] +transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.501, 0, 0) + +[node name="Panel3" parent="Menus" instance=ExtResource("1_qfa5o")] +transform = Transform3D(-1, 0, -8.74228e-08, 0, 1, 0, 8.74228e-08, 0, -1, 0, 0, -0.501) + +[node name="Panel4" parent="Menus" instance=ExtResource("1_qfa5o")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.501, 0, 0) + +[node name="AnimationPlayer" type="AnimationPlayer" parent="Menus"] +libraries = { +&"": SubResource("AnimationLibrary_3bwb0") +} + +[node name="Camera3D" type="Camera3D" parent="."] +transform = Transform3D(0.975535, 0, 0.219846, 0, 1, 0, -0.219846, 0, 0.975535, 0.86618, 0.217345, 1.76032) + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_qfa5o") diff --git a/menus/main/panel.tscn b/menus/main/panel.tscn new file mode 100644 index 0000000..04553cd --- /dev/null +++ b/menus/main/panel.tscn @@ -0,0 +1,113 @@ +[gd_scene load_steps=7 format=3 uid="uid://wlhsarkeqe8r"] + +[ext_resource type="PackedScene" uid="uid://tasbgr10p84c" path="res://menus/menu.tscn" id="1_3roig"] + +[sub_resource type="GDScript" id="GDScript_gfsnp"] +script/source = "# this whole code is from \"GUI in 3D\" +# which is something I downloaded a long time ago so no link + +extends Node3D + +var is_mouse_inside := false +var last_event_pos2D := Vector2() +var last_event_time := -1.0 + +@onready var node_viewport: SubViewport = $SubViewport +@onready var node_quad: MeshInstance3D = $MeshInstance3D +@onready var node_area: Area3D = $MeshInstance3D/Area3D + +func _ready() -> void: + node_area.mouse_entered.connect(_mouse_entered_area) + node_area.mouse_exited.connect(_mouse_exited_area) + node_area.input_event.connect(_mouse_input_event) + +func _mouse_entered_area() -> void: + is_mouse_inside = true + +func _mouse_exited_area() -> void: + is_mouse_inside = false + +func _unhandled_input(event: InputEvent) -> void: + for mouse_event in [InputEventMouseButton, InputEventMouseMotion, InputEventScreenDrag, InputEventScreenTouch]: + if is_instance_of(event, mouse_event): + return + node_viewport.push_input(event) + +func _mouse_input_event(_camera: Camera3D, event: InputEvent, event_position: Vector3, _normal: Vector3, _shape_idx: int) -> void: + var quad_mesh_size: Vector2 = node_quad.mesh.size + var now := Time.get_ticks_msec() / 1000.0 + + var event_pos3D := event_position + event_pos3D = node_quad.global_transform.affine_inverse() * event_pos3D + + var event_pos2D := Vector2() + if is_mouse_inside: + event_pos2D = Vector2(event_pos3D.x, -event_pos3D.y) + + event_pos2D.x = event_pos2D.x / quad_mesh_size.x + event_pos2D.y = event_pos2D.y / quad_mesh_size.y + + event_pos2D.x += 0.5 + event_pos2D.y += 0.5 + + event_pos2D.x *= node_viewport.size.x + event_pos2D.y *= node_viewport.size.y + + elif last_event_pos2D != null: + event_pos2D = last_event_pos2D + + event.position = event_pos2D + if event is InputEventMouse: + event.global_position = event_pos2D + + if event is InputEventMouseMotion or event is InputEventScreenDrag: + if last_event_pos2D == null: + event.relative = Vector2(0, 0) + else: + event.relative = event_pos2D - last_event_pos2D + event.velocity = event.relative / (now - last_event_time) + + last_event_pos2D = event_pos2D + last_event_time = now + node_viewport.push_input(event) + +# original code + +func change_menu(new_menu: Control): + $SubViewport/Menu.add(new_menu) +" + +[sub_resource type="QuadMesh" id="QuadMesh_gfsnp"] + +[sub_resource type="ViewportTexture" id="ViewportTexture_gfsnp"] +viewport_path = NodePath("SubViewport") + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_a5lkq"] +resource_local_to_scene = true +transparency = 1 +shading_mode = 0 +albedo_texture = SubResource("ViewportTexture_gfsnp") + +[sub_resource type="BoxShape3D" id="BoxShape3D_gfsnp"] +size = Vector3(1, 1, 0.01) + +[node name="Panel" type="Node3D"] +process_mode = 3 +script = SubResource("GDScript_gfsnp") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +mesh = SubResource("QuadMesh_gfsnp") +surface_material_override/0 = SubResource("StandardMaterial3D_a5lkq") + +[node name="Area3D" type="Area3D" parent="MeshInstance3D"] +collision_layer = 2 +input_capture_on_drag = true + +[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/Area3D"] +shape = SubResource("BoxShape3D_gfsnp") + +[node name="SubViewport" type="SubViewport" parent="."] +gui_embed_subwindows = true +render_target_update_mode = 4 + +[node name="Menu" parent="SubViewport" instance=ExtResource("1_3roig")] diff --git a/menus/main/save_file_manager.tscn b/menus/main/save_file_manager.tscn new file mode 100644 index 0000000..da7f052 --- /dev/null +++ b/menus/main/save_file_manager.tscn @@ -0,0 +1,102 @@ +[gd_scene load_steps=5 format=3 uid="uid://w5te3qujco7d"] + +[sub_resource type="GDScript" id="GDScript_a5kgg"] +script/source = "extends MarginContainer + +func _ready() -> void: + $HSplitContainer/CenterContainer/Label.hide() + + +func _on_button_pressed() -> void: + $HSplitContainer/CenterContainer/Label.show() + $AnimationPlayer.play(\"add_information\") +" + +[sub_resource type="Animation" id="Animation_a5kgg"] +resource_name = "add_information" +length = 0.2 +step = 0.2 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("HSplitContainer/CenterContainer:size_flags_stretch_ratio") +tracks/0/interp = 2 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0.0, 2.0] +} + +[sub_resource type="Animation" id="Animation_xs01b"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("HSplitContainer/CenterContainer:size_flags_stretch_ratio") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_36lt1"] +_data = { +&"RESET": SubResource("Animation_xs01b"), +&"add_information": SubResource("Animation_a5kgg") +} + +[node name="SaveFileManager" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = SubResource("GDScript_a5kgg") + +[node name="HSplitContainer" type="HSplitContainer" parent="."] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="HSplitContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +alignment = 1 + +[node name="Button" type="Button" parent="HSplitContainer/VBoxContainer"] +layout_mode = 2 +text = "Save file" + +[node name="Button2" type="Button" parent="HSplitContainer/VBoxContainer"] +layout_mode = 2 +text = "Save file" + +[node name="Button3" type="Button" parent="HSplitContainer/VBoxContainer"] +layout_mode = 2 +text = "Save file" + +[node name="CenterContainer" type="CenterContainer" parent="HSplitContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 0.0 + +[node name="Label" type="Label" parent="HSplitContainer/CenterContainer"] +show_behind_parent = true +layout_mode = 2 +text = "Information" + +[node name="AnimationPlayer" type="AnimationPlayer" parent="."] +libraries = { +&"": SubResource("AnimationLibrary_36lt1") +} + +[connection signal="pressed" from="HSplitContainer/VBoxContainer/Button" to="." method="_on_button_pressed"] diff --git a/menus/main/start_menu.tscn b/menus/main/start_menu.tscn new file mode 100644 index 0000000..9182cc7 --- /dev/null +++ b/menus/main/start_menu.tscn @@ -0,0 +1,54 @@ +[gd_scene load_steps=2 format=3 uid="uid://dys7qyy4b3gjt"] + +[sub_resource type="GDScript" id="GDScript_vfuxb"] +script/source = "extends Control + +signal request_start +signal request_settings + +func _on_btn_start_pressed() -> void: + request_start.emit() + +func _on_btn_settings_pressed() -> void: + request_settings.emit() + +func _on_btn_exit_pressed() -> void: + get_tree().quit() +" + +[node name="StartMenu" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_vfuxb") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 14 +anchor_top = 0.5 +anchor_right = 1.0 +anchor_bottom = 0.5 +offset_top = -50.5 +offset_bottom = 50.5 +grow_horizontal = 2 +grow_vertical = 2 +alignment = 1 + +[node name="BtnStart" type="Button" parent="VBoxContainer"] +layout_mode = 2 +text = "Start the game!" + +[node name="BtnSettings" type="Button" parent="VBoxContainer"] +layout_mode = 2 +text = "Check out the settings" + +[node name="BtnExit" type="Button" parent="VBoxContainer"] +layout_mode = 2 +text = "Exit the game" + +[connection signal="pressed" from="VBoxContainer/BtnStart" to="." method="_on_btn_start_pressed"] +[connection signal="pressed" from="VBoxContainer/BtnSettings" to="." method="_on_btn_settings_pressed"] +[connection signal="pressed" from="VBoxContainer/BtnExit" to="." method="_on_btn_exit_pressed"] diff --git a/menus/menu.tscn b/menus/menu.tscn new file mode 100644 index 0000000..dddea27 --- /dev/null +++ b/menus/menu.tscn @@ -0,0 +1,99 @@ +[gd_scene load_steps=6 format=3 uid="uid://tasbgr10p84c"] + +[sub_resource type="GDScript" id="GDScript_18a3y"] +script/source = "extends MarginContainer + +func add(node: Control): + var add_to := $VSplitContainer/MarginContainer/ColorRect + var children := add_to.get_children(true) + for child in children: + child.queue_free() + + var regex := RegEx.new() + regex.compile(\"([A-Z])\") + var menu_name := regex.sub(node.name, \" $1\", true, 1) + $VSplitContainer/Label.text = menu_name + add_to.add_child(node) + $VSplitContainer/AnimationPlayer.play(\"split_offset\") + + #await get_tree().create_timer(3.0).timeout + #$VSplitContainer/AnimationPlayer.play_backwards(\"split_offset\") +" + +[sub_resource type="Animation" id="Animation_y8e4h"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:split_offset") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [500] +} + +[sub_resource type="Animation" id="Animation_85u52"] +resource_name = "split_offset" +length = 0.5 +step = 0.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath(".:split_offset") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [500, 0] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_hl3ms"] +_data = { +&"RESET": SubResource("Animation_y8e4h"), +&"split_offset": SubResource("Animation_85u52") +} + +[sub_resource type="LabelSettings" id="LabelSettings_2d4ws"] +font_size = 48 + +[node name="Menu" type="MarginContainer"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 20 +theme_override_constants/margin_top = 20 +theme_override_constants/margin_right = 20 +theme_override_constants/margin_bottom = 20 +script = SubResource("GDScript_18a3y") + +[node name="VSplitContainer" type="VSplitContainer" parent="."] +layout_mode = 2 +split_offset = 500 +dragger_visibility = 1 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="VSplitContainer"] +libraries = { +&"": SubResource("AnimationLibrary_hl3ms") +} + +[node name="Label" type="Label" parent="VSplitContainer"] +layout_mode = 2 +text = "MENU NAME" +label_settings = SubResource("LabelSettings_2d4ws") +horizontal_alignment = 1 +uppercase = true + +[node name="MarginContainer" type="MarginContainer" parent="VSplitContainer"] +layout_mode = 2 +theme_override_constants/margin_top = 20 + +[node name="ColorRect" type="ColorRect" parent="VSplitContainer/MarginContainer"] +layout_mode = 2 +color = Color(0, 0, 0, 1) diff --git a/project.godot b/project.godot index 605a759..6595a5a 100644 --- a/project.godot +++ b/project.godot @@ -13,7 +13,7 @@ config_version=5 config/name="DreamBall" config/description="Manipulate the gravity to make a ball go through every ring! https://kitsunes.dev/Taevas/DreamBall" -config/version="20250323.0" +config/version="20250326.0" run/main_scene="res://index.tscn" config/features=PackedStringArray("4.4", "GL Compatibility") boot_splash/show_image=false