diff --git a/modules/going/game_ui.cpp b/modules/going/game_ui.cpp index 69b37c27..6bf141d0 100644 --- a/modules/going/game_ui.cpp +++ b/modules/going/game_ui.cpp @@ -1,10 +1,12 @@ #include "game_ui.h" +#include "core/config/engine.h" GameUI *GameUI::singleton_instance{nullptr}; void GameUI::_bind_methods() { ClassDB::bind_method(D_METHOD("display_message", "text"), &self_type::display_message); ClassDB::bind_static_method("GameUI", D_METHOD("get_singleton"), &self_type::get_singleton); + ClassDB::bind_method(D_METHOD("toggle_paused"), &self_type::toggle_paused); } void GameUI::_notification(int what) { @@ -14,6 +16,9 @@ void GameUI::_notification(int what) { if(what == NOTIFICATION_ENTER_TREE) { ERR_FAIL_COND_EDMSG(self_type::singleton_instance != nullptr, "GameUI instance already exists, deleting second instance"); self_type::singleton_instance = this; + this->set_process_unhandled_input(true); + this->pause_menu = Object::cast_to(this->get_node(NodePath("%PauseMenu"))); + this->pause_menu->hide(); } else if(what == NOTIFICATION_EXIT_TREE) { self_type::singleton_instance = nullptr; } @@ -23,6 +28,12 @@ void GameUI::_notification(int what) { } } +void GameUI::unhandled_input(Ref const &event) { + if(event->is_action_pressed("menu")) { + this->toggle_paused(); + } +} + GameUI *GameUI::get_singleton() { return self_type::singleton_instance; } @@ -31,3 +42,13 @@ void GameUI::display_message(String text) { this->message->set_text(text); this->clear_message_timer->start(0.0); } + +void GameUI::toggle_paused() { + if(this->get_tree()->is_paused()) { + this->get_tree()->set_pause(false); + this->pause_menu->hide(); + } else { + this->get_tree()->set_pause(true); + this->pause_menu->show(); + } +} diff --git a/modules/going/game_ui.h b/modules/going/game_ui.h index 648f628c..d3d74d0a 100644 --- a/modules/going/game_ui.h +++ b/modules/going/game_ui.h @@ -10,11 +10,14 @@ class GameUI : public CanvasLayer { GDCLASS(GameUI, CanvasLayer); static void _bind_methods(); void _notification(int what); + virtual void unhandled_input(Ref const &event) override; static GameUI *singleton_instance; public: static GameUI *get_singleton(); void display_message(String text); + void toggle_paused(); private: + Control *pause_menu{nullptr}; RichTextLabel *message{nullptr}; Timer *clear_message_timer{nullptr}; }; diff --git a/modules/going/player_body.cpp b/modules/going/player_body.cpp index e956a9a3..182f5798 100644 --- a/modules/going/player_body.cpp +++ b/modules/going/player_body.cpp @@ -65,6 +65,7 @@ void PlayerBody::_notification(int what) { void PlayerBody::enter_tree() { this->set_process(true); this->set_physics_process(true); + this->set_process_unhandled_input(true); this->model = Object::cast_to(this->get_node(NodePath("character"))); this->anim = Object::cast_to(this->get_node(NodePath("character/AnimationPlayer"))); this->camera = Object::cast_to(this->get_node(NodePath("Camera3D"))); @@ -76,6 +77,12 @@ void PlayerBody::ready() { this->last_checkpoint = Checkpoint::save_new(this); } +void PlayerBody::unhandled_input(Ref const &event) { + if(event->is_action_pressed("reload")) { + this->load_checkpoint(); + } +} + void PlayerBody::process(double delta) { Input *input{Input::get_singleton()}; this->movement = Vector2{ diff --git a/modules/going/player_body.h b/modules/going/player_body.h index d90ef35b..0f212bbd 100644 --- a/modules/going/player_body.h +++ b/modules/going/player_body.h @@ -13,6 +13,7 @@ class PlayerBody : public CharacterBody3D { void _notification(int what); void enter_tree(); void ready(); + virtual void unhandled_input(Ref const &event) override; void process(double delta); void physics_process(double delta); diff --git a/project/objects/bash_pickup.tscn b/project/objects/bash_pickup.tscn index 249c9e84..ecb57f8f 100644 --- a/project/objects/bash_pickup.tscn +++ b/project/objects/bash_pickup.tscn @@ -9,7 +9,7 @@ func _on_body_entered(body: Node3D) -> void: if body.is_class(\"PlayerBody\"): body.can_bash = true queue_free() - GameUI.get_singleton().display_message(\"Bash through obstacles by pressing [img height=\\\"100\\\"]uid://baw7deolvkudx[/img] and [img height=\\\"100\\\"]uid://cfy8lgh61hsxg[/img] simultaneously\") + GameUI.get_singleton().display_message(\"Bash through obstacles by pressing [img height=\\\"100\\\"]uid://baw7deolvkudx[/img]/shift and [img height=\\\"100\\\"]uid://cfy8lgh61hsxg[/img]/C simultaneously\") (body as PlayerBody).save_checkpoint() func _physics_process(delta): diff --git a/project/objects/jump_pickup.tscn b/project/objects/jump_pickup.tscn index 6bb600e0..279c68f4 100644 --- a/project/objects/jump_pickup.tscn +++ b/project/objects/jump_pickup.tscn @@ -9,7 +9,7 @@ func _on_body_entered(body: Node3D) -> void: if body.is_class(\"PlayerBody\"): body.can_jump = true queue_free() - GameUI.get_singleton().display_message(\"Jump by pressing [img height=\\\"100\\\"]uid://baw7deolvkudx[/img] and [img height=\\\"100\\\"]uid://d1kw2owusg8fn[/img] simultaneously\") + GameUI.get_singleton().display_message(\"Jump by pressing [img height=\\\"100\\\"]uid://baw7deolvkudx[/img]/shift and [img height=\\\"100\\\"]uid://d1kw2owusg8fn[/img]/space simultaneously\") (body as PlayerBody).save_checkpoint() func _physics_process(delta): diff --git a/project/project.godot b/project/project.godot index 096f9fa0..beffeeaa 100644 --- a/project/project.godot +++ b/project/project.godot @@ -62,24 +62,28 @@ move_left={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_right={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_forward={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_back={ "deadzone": 0.2, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"location":0,"echo":false,"script":null) , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } split_step={ @@ -100,6 +104,18 @@ bash={ , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":67,"key_label":0,"unicode":99,"location":0,"echo":false,"script":null) ] } +menu={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":true,"script":null) +] +} +reload={ +"deadzone": 0.2, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":82,"key_label":0,"unicode":114,"location":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":12,"pressure":0.0,"pressed":true,"script":null) +] +} [layer_names] diff --git a/project/scenes/main_menu.tscn b/project/scenes/main_menu.tscn index 6b93009e..623ed7c7 100644 --- a/project/scenes/main_menu.tscn +++ b/project/scenes/main_menu.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=9 format=3 uid="uid://cnau7sr4mu3gf"] +[gd_scene load_steps=10 format=3 uid="uid://cnau7sr4mu3gf"] [ext_resource type="PackedScene" uid="uid://d0w3tum281vei" path="res://objects/level.tscn" id="1_l6cm7"] [ext_resource type="Texture2D" uid="uid://qxwsryrw0ny4" path="res://rendering/kloppenheim_06_4k.exr" id="2_ekxnf"] @@ -49,6 +49,7 @@ func _ready(): func updated_scale(): ValleyRoot.set_render_factor(container.stretch_shrink) $Label.text = \"%.2fx\" % (1.0/container.stretch_shrink) + $Increase.disabled = container.stretch_shrink == 1.0 func _on_lower_pressed() -> void: container.stretch_shrink += 1 @@ -60,6 +61,13 @@ func _on_increase_pressed() -> void: updated_scale() " +[sub_resource type="GDScript" id="GDScript_bqqt6"] +script/source = "extends Button + +func _on_button_up() -> void: + self.get_tree().quit(0) +" + [node name="MainMenu" type="Control"] layout_mode = 3 anchors_preset = 15 @@ -114,8 +122,9 @@ grow_vertical = 0 [node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"] layout_mode = 2 +alignment = 1 -[node name="Button" type="Button" parent="PanelContainer/VBoxContainer"] +[node name="Start" type="Button" parent="PanelContainer/VBoxContainer"] layout_mode = 2 focus_neighbor_bottom = NodePath("../Resolution/Lower") theme_override_font_sizes/font_size = 50 @@ -134,8 +143,9 @@ script = SubResource("GDScript_ekxnf") [node name="Lower" type="Button" parent="PanelContainer/VBoxContainer/Resolution"] layout_mode = 2 -focus_neighbor_top = NodePath("../../Button") +focus_neighbor_top = NodePath("../../Start") focus_neighbor_right = NodePath("../Increase") +focus_neighbor_bottom = NodePath("../../Quit") theme_override_font_sizes/font_size = 25 text = "<" @@ -149,10 +159,19 @@ horizontal_alignment = 1 [node name="Increase" type="Button" parent="PanelContainer/VBoxContainer/Resolution"] layout_mode = 2 focus_neighbor_left = NodePath("../Lower") -focus_neighbor_top = NodePath("../../Button") +focus_neighbor_top = NodePath("../../Start") +focus_neighbor_bottom = NodePath("../../Quit") theme_override_font_sizes/font_size = 25 text = ">" +[node name="Quit" type="Button" parent="PanelContainer/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +focus_neighbor_top = NodePath("../Resolution/Lower") +theme_override_font_sizes/font_size = 25 +text = "Quit" +script = SubResource("GDScript_bqqt6") + [node name="TextureRect" type="TextureRect" parent="."] layout_mode = 1 anchors_preset = 13 @@ -167,6 +186,7 @@ texture = ExtResource("3_bqqt6") expand_mode = 2 stretch_mode = 4 -[connection signal="button_up" from="PanelContainer/VBoxContainer/Button" to="PanelContainer/VBoxContainer/Button" method="_on_button_up"] +[connection signal="button_up" from="PanelContainer/VBoxContainer/Start" to="PanelContainer/VBoxContainer/Start" method="_on_button_up"] [connection signal="pressed" from="PanelContainer/VBoxContainer/Resolution/Lower" to="PanelContainer/VBoxContainer/Resolution" method="_on_lower_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/Resolution/Increase" to="PanelContainer/VBoxContainer/Resolution" method="_on_increase_pressed"] +[connection signal="button_up" from="PanelContainer/VBoxContainer/Quit" to="PanelContainer/VBoxContainer/Quit" method="_on_button_up"] diff --git a/project/scenes/valley.tscn b/project/scenes/valley.tscn index bd05d31a..03c25b8a 100644 --- a/project/scenes/valley.tscn +++ b/project/scenes/valley.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=22 format=3 uid="uid://sofv1apr4467"] +[gd_scene load_steps=24 format=3 uid="uid://sofv1apr4467"] [ext_resource type="PackedScene" uid="uid://dy4yl1paa8whs" path="res://ui/ui.tscn" id="1_a2vvy"] [ext_resource type="PackedScene" uid="uid://dcgsrdacswacl" path="res://objects/player.tscn" id="2_pvuhy"] @@ -66,7 +66,7 @@ script/source = "extends CheckpointArea func _on_body_entered(body: Node3D) -> void: if body.is_class(\"PlayerBody\"): - GameUI.get_singleton().display_message(\"Turn corners quickly by pressing [img height=\\\"100\\\"]uid://baw7deolvkudx[/img] while turning\") + GameUI.get_singleton().display_message(\"Turn corners quickly by pressing [img height=\\\"100\\\"]uid://baw7deolvkudx[/img]/shift while turning\") " [sub_resource type="BoxShape3D" id="BoxShape3D_l73gk"] @@ -81,6 +81,17 @@ size = Vector3(8.24559, 12.443, 12.8204) [sub_resource type="BoxShape3D" id="BoxShape3D_2lbax"] size = Vector3(36.8259, 22.1272, 32.501) +[sub_resource type="GDScript" id="GDScript_m3qr3"] +script/source = "extends CheckpointArea + +func _on_body_entered(body: Node3D) -> void: + if body.is_class(\"PlayerBody\"): + GameUI.get_singleton().display_message(\"Press [img]uid://d4c83k2utears[/img]/R to reload last checkpoint\") +" + +[sub_resource type="BoxShape3D" id="BoxShape3D_fmd53"] +size = Vector3(10.512, 4, 8.93457) + [sub_resource type="BoxShape3D" id="BoxShape3D_a2vvy"] size = Vector3(85.4894, 10.9026, 9.25488) @@ -290,6 +301,17 @@ collision_mask = 2 shape = SubResource("BoxShape3D_l73gk") debug_color = Color(0.255, 0.9, 0, 1) +[node name="CheckpointArea13" type="CheckpointArea" parent="SubViewportContainer/SubViewport"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 151.633, 2.56461, 235.603) +collision_layer = 2 +collision_mask = 2 +script = SubResource("GDScript_m3qr3") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="SubViewportContainer/SubViewport/CheckpointArea13"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.32373, -3.14111) +shape = SubResource("BoxShape3D_fmd53") +debug_color = Color(0.255, 0.9, 0, 1) + [node name="CheckpointArea15" type="CheckpointArea" parent="SubViewportContainer/SubViewport"] transform = Transform3D(0.999984, -5.03508e-10, 0.00572465, 5.03483e-10, 1, 5.78298e-12, -0.00572465, -2.89943e-12, 0.999984, 201.691, -1.75429, 232.065) collision_layer = 2 @@ -303,3 +325,4 @@ debug_color = Color(0.255, 0.9, 0, 1) [connection signal="body_entered" from="SubViewportContainer/SubViewport/VictoryArea" to="SubViewportContainer/SubViewport/VictoryArea" method="_on_body_entered"] [connection signal="body_entered" from="SubViewportContainer/SubViewport/ReloadArea2" to="SubViewportContainer/SubViewport/ReloadArea2" method="_on_body_entered"] [connection signal="body_entered" from="SubViewportContainer/SubViewport/CheckpointArea" to="SubViewportContainer/SubViewport/CheckpointArea" method="_on_body_entered"] +[connection signal="body_entered" from="SubViewportContainer/SubViewport/CheckpointArea13" to="SubViewportContainer/SubViewport/CheckpointArea13" method="_on_body_entered"] diff --git a/project/ui/ui.tscn b/project/ui/ui.tscn index 5efbf118..d5a63b01 100644 --- a/project/ui/ui.tscn +++ b/project/ui/ui.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=4 format=3 uid="uid://dy4yl1paa8whs"] +[gd_scene load_steps=5 format=3 uid="uid://dy4yl1paa8whs"] [ext_resource type="Texture2D" uid="uid://bglfaie21avpt" path="res://ui/vignette.png" id="1_nb4k0"] @@ -24,6 +24,21 @@ void fragment() { [sub_resource type="ShaderMaterial" id="ShaderMaterial_uxov2"] shader = SubResource("Shader_ykyjo") +[sub_resource type="GDScript" id="GDScript_nb4k0"] +script/source = "extends CenterContainer + +func _on_resume_pressed() -> void: + $\"..\".toggle_paused() + +func _on_visibility_changed() -> void: + if self.is_node_ready() and self.is_visible_in_tree(): + $PanelContainer/VBoxContainer/Resume.grab_focus() + +func _on_quit_pressed() -> void: + get_tree().paused = false + get_tree().change_scene_to_file(\"res://scenes/main_menu.tscn\") +" + [node name="CanvasLayer" type="GameUI"] [node name="Vignette" type="TextureRect" parent="."] @@ -46,7 +61,7 @@ anchor_bottom = 1.0 offset_top = 317.0 grow_horizontal = 2 grow_vertical = 2 -theme_override_font_sizes/normal_font_size = 74 +theme_override_font_sizes/normal_font_size = 50 bbcode_enabled = true text = "Good Luck!" horizontal_alignment = 1 @@ -59,4 +74,31 @@ one_shot = true autostart = true ignore_time_scale = true +[node name="PauseMenu" type="CenterContainer" parent="."] +unique_name_in_owner = true +process_mode = 2 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = SubResource("GDScript_nb4k0") + +[node name="PanelContainer" type="PanelContainer" parent="PauseMenu"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="PauseMenu/PanelContainer"] +layout_mode = 2 + +[node name="Resume" type="Button" parent="PauseMenu/PanelContainer/VBoxContainer"] +layout_mode = 2 +text = "Resume" + +[node name="Quit" type="Button" parent="PauseMenu/PanelContainer/VBoxContainer"] +layout_mode = 2 +text = "Quit" + [connection signal="timeout" from="MessageLabel/ClearMessageTimer" to="MessageLabel" method="set_text" flags=3 binds= [""]] +[connection signal="visibility_changed" from="PauseMenu" to="PauseMenu" method="_on_visibility_changed"] +[connection signal="pressed" from="PauseMenu/PanelContainer/VBoxContainer/Resume" to="PauseMenu" method="_on_resume_pressed"] +[connection signal="pressed" from="PauseMenu/PanelContainer/VBoxContainer/Quit" to="PauseMenu" method="_on_quit_pressed"] diff --git a/project/ui/xbox_dpad_down_outline.svg b/project/ui/xbox_dpad_down_outline.svg new file mode 100644 index 00000000..aad8f49f --- /dev/null +++ b/project/ui/xbox_dpad_down_outline.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/project/ui/xbox_dpad_down_outline.svg.import b/project/ui/xbox_dpad_down_outline.svg.import new file mode 100644 index 00000000..0ab6a1b7 --- /dev/null +++ b/project/ui/xbox_dpad_down_outline.svg.import @@ -0,0 +1,37 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d4c83k2utears" +path="res://.godot/imported/xbox_dpad_down_outline.svg-dd158cbb7cc0c2c3fd1b26fcc6533b70.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://ui/xbox_dpad_down_outline.svg" +dest_files=["res://.godot/imported/xbox_dpad_down_outline.svg-dd158cbb7cc0c2c3fd1b26fcc6533b70.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 +svg/scale=1.0 +editor/scale_with_editor_scale=false +editor/convert_colors_with_editor_theme=false