diff --git a/Characters/Character.cs b/Characters/Character.cs index 785d11c..9c02342 100644 --- a/Characters/Character.cs +++ b/Characters/Character.cs @@ -30,7 +30,7 @@ public partial class Character : CharacterBody2D, IFaction public float Stealth { get; protected set; } = 0; [Signal] - public delegate void HealthChangedEventHandler(float oldHP, float newHP); + public delegate void HealthChangedEventHandler(Events.HealthChangedArgs args); [Signal] public delegate void HurtEventHandler(Events.HurtArgs args); @@ -60,6 +60,13 @@ public partial class Character : CharacterBody2D, IFaction return; } + var args = new Events.HealthChangedArgs + { + OldHealth = _health, + NewHealth = value, + }; + EmitSignal(SignalName.HealthChanged, args); + _health = value; if (_health <= 0) { diff --git a/Characters/Player.cs b/Characters/Player.cs index b845271..83c22f9 100644 --- a/Characters/Player.cs +++ b/Characters/Player.cs @@ -40,6 +40,12 @@ public sealed partial class Player : Character AttackAnimation.Play("sword"); } }; + + HealthChanged += (args) => + { + var signal = Events.EventBus.SignalName.PlayerHealthChanged; + this.GetEventBus().EmitSignal(signal, args); + }; } public override void _Input(InputEvent @event) diff --git a/Events/EventBus.cs b/Events/EventBus.cs index 7a8d46b..2661ef1 100644 --- a/Events/EventBus.cs +++ b/Events/EventBus.cs @@ -6,4 +6,13 @@ public partial class EventBus : Node { [Signal] public delegate void RequestMoveToAreaEventHandler(RequestAreaArgs args); + + [Signal] + public delegate void PlayerDeathEventHandler(HurtArgs args); + + [Signal] + public delegate void PlayerHurtEventHandler(HurtArgs args); + + [Signal] + public delegate void PlayerHealthChangedEventHandler(HealthChangedArgs args); } diff --git a/Extensions/Node.cs b/Extensions/Node.cs index d167a2c..34f47b6 100644 --- a/Extensions/Node.cs +++ b/Extensions/Node.cs @@ -66,4 +66,15 @@ public static class NodeExtensions { return node.GetNode("/root/World"); } + + public static CanvasLayer GetUI(this Node node) + { + return node.GetNode("/root/BaseUI"); + } + + public static UI.UIController GetMainUI(this Node node) + { + return node.GetNode("/root/BaseUI/" + + "SubViewportContainer/UIViewport/CanvasLayer/MainUILayer/Main"); + } } diff --git a/Scenes/Level.tscn b/Scenes/Level.tscn index 28f3a98..e04588f 100644 --- a/Scenes/Level.tscn +++ b/Scenes/Level.tscn @@ -1,82 +1,14 @@ -[gd_scene load_steps=6 format=3 uid="uid://1pb3mpmrl7lc"] +[gd_scene load_steps=3 format=3 uid="uid://1pb3mpmrl7lc"] [ext_resource type="Script" path="res://Utils/World.cs" id="1_1k6ew"] -[ext_resource type="PackedScene" uid="uid://bxo553hblp6nf" path="res://UI/HealthBar.tscn" id="3_5rhge"] -[ext_resource type="Script" path="res://UI/UIController.cs" id="3_fe62s"] -[ext_resource type="PackedScene" uid="uid://01d24ij5av1y" path="res://UI/BossBar.tscn" id="5_8njq4"] -[ext_resource type="PackedScene" uid="uid://73jm5qjy52vq" path="res://Dialogue/balloon.tscn" id="6_2bdwl"] +[ext_resource type="PackedScene" uid="uid://c271rdjhd1gfo" path="res://UI/Base.tscn" id="2_mm0qt"] -[node name="World" type="Node2D" node_paths=PackedStringArray("UIController", "MusicPlayer", "DialogueBalloon")] +[node name="World" type="Node2D" node_paths=PackedStringArray("MusicPlayer", "DialogueBalloon")] script = ExtResource("1_1k6ew") -UIController = NodePath("CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer/UI") MusicPlayer = NodePath("MusicPlayer") DialogueBalloon = NodePath("CanvasLayer/SubViewportContainer/UIViewport/DialogBalloon") -[node name="CanvasLayer" type="CanvasLayer" parent="."] - -[node name="SubViewportContainer" type="SubViewportContainer" parent="CanvasLayer"] -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -stretch = true -stretch_shrink = 3 - -[node name="UIViewport" type="SubViewport" parent="CanvasLayer/SubViewportContainer"] -transparent_bg = true -handle_input_locally = false -size = Vector2i(640, 360) -render_target_update_mode = 4 - -[node name="DialogBalloon" parent="CanvasLayer/SubViewportContainer/UIViewport" instance=ExtResource("6_2bdwl")] -layer = 2 - -[node name="CanvasLayer" type="CanvasLayer" parent="CanvasLayer/SubViewportContainer/UIViewport"] - -[node name="UI" type="Control" parent="CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer" node_paths=PackedStringArray("BossBar")] -z_index = 128 -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -script = ExtResource("3_fe62s") -BossBar = NodePath("Bottom/BossBar") - -[node name="Top" type="HBoxContainer" parent="CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer/UI"] -layout_mode = 1 -anchors_preset = 10 -anchor_right = 1.0 -offset_bottom = 40.0 -grow_horizontal = 2 - -[node name="Margin" type="MarginContainer" parent="CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer/UI/Top"] -layout_mode = 2 -theme_override_constants/margin_left = 16 -theme_override_constants/margin_top = 16 - -[node name="HealthBar" parent="CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer/UI/Top/Margin" instance=ExtResource("3_5rhge")] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="Bottom" type="HBoxContainer" parent="CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer/UI"] -layout_mode = 1 -anchors_preset = 12 -anchor_top = 1.0 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_top = -44.0 -grow_horizontal = 2 -grow_vertical = 0 -alignment = 1 - -[node name="BossBar" parent="CanvasLayer/SubViewportContainer/UIViewport/CanvasLayer/UI/Bottom" instance=ExtResource("5_8njq4")] -visible = false -layout_mode = 2 +[node name="CanvasLayer" parent="." instance=ExtResource("2_mm0qt")] [node name="DebugUI" type="CanvasLayer" parent="."] layer = 2 @@ -90,3 +22,4 @@ grow_horizontal = 2 grow_vertical = 2 [node name="MusicPlayer" type="AudioStreamPlayer" parent="."] +bus = &"Music" diff --git a/Scenes/Maps/Arena.tscn b/Scenes/Maps/Arena.tscn index 1ebf58e..e1687d6 100644 --- a/Scenes/Maps/Arena.tscn +++ b/Scenes/Maps/Arena.tscn @@ -11,7 +11,7 @@ [ext_resource type="PackedScene" uid="uid://dldnp8eunxj3q" path="res://BoundingBoxes/InteractionTrigger.tscn" id="9_3401j"] [ext_resource type="Script" path="res://BoundingBoxes/ConnectorBox.cs" id="9_fg062"] -[sub_resource type="ShaderMaterial" id="ShaderMaterial_ltk3d"] +[sub_resource type="ShaderMaterial" id="ShaderMaterial_pg4a6"] resource_local_to_scene = true shader = ExtResource("5_h8k5p") shader_parameter/color = Vector4(1, 1, 1, 1) @@ -113,7 +113,7 @@ visible = false position = Vector2(120, -112) [node name="Doc" parent="Entities" index="0" instance=ExtResource("4_ej0f3")] -material = SubResource("ShaderMaterial_ltk3d") +material = SubResource("ShaderMaterial_pg4a6") [node name="PointLight2D" type="PointLight2D" parent="Entities" index="1"] position = Vector2(168, -42) diff --git a/UI/Base.tscn b/UI/Base.tscn new file mode 100644 index 0000000..50aacf4 --- /dev/null +++ b/UI/Base.tscn @@ -0,0 +1,77 @@ +[gd_scene load_steps=5 format=3 uid="uid://c271rdjhd1gfo"] + +[ext_resource type="PackedScene" uid="uid://73jm5qjy52vq" path="res://Dialogue/balloon.tscn" id="1_atjb1"] +[ext_resource type="Script" path="res://UI/UIController.cs" id="2_b4b6l"] +[ext_resource type="PackedScene" uid="uid://bxo553hblp6nf" path="res://UI/HealthBar.tscn" id="3_j1j6h"] +[ext_resource type="PackedScene" uid="uid://01d24ij5av1y" path="res://UI/BossBar.tscn" id="4_igi28"] + +[node name="BaseUI" type="CanvasLayer"] + +[node name="SubViewportContainer" type="SubViewportContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +stretch = true +stretch_shrink = 3 + +[node name="UIViewport" type="SubViewport" parent="SubViewportContainer"] +transparent_bg = true +handle_input_locally = false +size = Vector2i(640, 360) +render_target_update_mode = 4 + +[node name="DialogBalloon" parent="SubViewportContainer/UIViewport" instance=ExtResource("1_atjb1")] +layer = 2 + +[node name="MainUILayer" type="CanvasLayer" parent="SubViewportContainer/UIViewport"] + +[node name="Main" type="Control" parent="SubViewportContainer/UIViewport/MainUILayer" node_paths=PackedStringArray("BossBar")] +z_index = 128 +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("2_b4b6l") +BossBar = NodePath("Bottom/BossBar") + +[node name="Top" type="HBoxContainer" parent="SubViewportContainer/UIViewport/MainUILayer/Main"] +layout_mode = 1 +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 40.0 +grow_horizontal = 2 + +[node name="Margin" type="MarginContainer" parent="SubViewportContainer/UIViewport/MainUILayer/Main/Top"] +layout_mode = 2 +theme_override_constants/margin_left = 16 +theme_override_constants/margin_top = 16 + +[node name="HealthBar" parent="SubViewportContainer/UIViewport/MainUILayer/Main/Top/Margin" instance=ExtResource("3_j1j6h")] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Bottom" type="HBoxContainer" parent="SubViewportContainer/UIViewport/MainUILayer/Main"] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -44.0 +grow_horizontal = 2 +grow_vertical = 0 +alignment = 1 + +[node name="BossBar" parent="SubViewportContainer/UIViewport/MainUILayer/Main/Bottom" instance=ExtResource("4_igi28")] +visible = false +layout_mode = 2 + +[node name="Location" type="Control" parent="SubViewportContainer/UIViewport/MainUILayer/Main"] +anchors_preset = 0 +offset_right = 40.0 +offset_bottom = 40.0 diff --git a/UI/HealthBar.cs b/UI/HealthBar.cs index 896e59a..79345fd 100644 --- a/UI/HealthBar.cs +++ b/UI/HealthBar.cs @@ -1,4 +1,5 @@ using Godot; +using SupaLidlGame.Extensions; namespace SupaLidlGame.UI; @@ -9,5 +10,9 @@ public partial class HealthBar : Control public override void _Ready() { ProgressBar = GetNode("TextureProgressBar"); + this.GetEventBus().PlayerHealthChanged += (args) => + { + ProgressBar.Value = args.NewHealth; + }; } } diff --git a/Utils/World.cs b/Utils/World.cs index f3c0149..0d26ffd 100644 --- a/Utils/World.cs +++ b/Utils/World.cs @@ -19,7 +19,6 @@ public partial class World : Node [Export] public Boss CurrentBoss { get; set; } - [Export] public UI.UIController UIController { get; set; } [Export] @@ -30,11 +29,10 @@ public partial class World : Node { get { - if (_dialogueBalloon is null || !IsInstanceValid(_dialogueBalloon)) + if (!IsDialogueOpen) { var scene = GD.Load("res://Dialogue/balloon.tscn"); _dialogueBalloon = scene.Instantiate(); - //_uiViewport.AddChild(_dialogueBalloon); _uiViewport.AddChild(_dialogueBalloon); } return _dialogueBalloon; @@ -49,6 +47,11 @@ public partial class World : Node } } + public bool IsDialogueOpen + { + get => _dialogueBalloon is not null && IsInstanceValid(_dialogueBalloon); + } + private Dialogue.Balloon _dialogueBalloon; private SubViewport _uiViewport; @@ -89,6 +92,14 @@ public partial class World : Node Godot.RenderingServer.SetDefaultClearColor(Godot.Colors.Black); + UIController = this.GetMainUI(); + + EventBus = this.GetEventBus(); + EventBus.RequestMoveToArea += (Events.RequestAreaArgs args) => + { + MoveToArea(args.Area, args.Connector); + }; + _uiViewport = GetNode("CanvasLayer/SubViewportContainer/UIViewport"); // create a player (currently unparented) @@ -97,12 +108,6 @@ public partial class World : Node // TODO: create start menu and load game from there LoadGame(); - EventBus = this.GetEventBus(); - EventBus.RequestMoveToArea += (Events.RequestAreaArgs args) => - { - MoveToArea(args.Area, args.Connector); - }; - base._Ready(); } @@ -224,12 +229,14 @@ public partial class World : Node }; }; + /* CurrentPlayer.Hurt += (Events.HurtArgs args) => { // TODO: move this to UI controller and add a setup method var bar = UIController.GetNode("Top/Margin/HealthBar"); bar.ProgressBar.Value = args.NewHealth; }; + */ return CurrentPlayer; } diff --git a/project.godot b/project.godot index 873cf7c..55cbffc 100644 --- a/project.godot +++ b/project.godot @@ -20,6 +20,7 @@ config/icon="res://icon.svg" DialogueManager="*res://addons/dialogue_manager/dialogue_manager.gd" GlobalState="*res://State/Global/GlobalState.cs" EventBus="*res://Events/EventBus.cs" +BaseUI="*res://UI/Base.tscn" World="*res://Scenes/Level.tscn" DebugConsole="*res://Debug/DebugConsole.cs" Panku="*res://addons/panku_console/console.tscn" @@ -50,6 +51,7 @@ ui_accept={ "deadzone": 0.5, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194309,"physical_keycode":0,"key_label":0,"unicode":4194309,"echo":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194310,"physical_keycode":0,"key_label":0,"unicode":4194310,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null) ] } ui_left={ @@ -80,16 +82,19 @@ roll={ "deadzone": 0.5, "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":3,"pressed":false,"double_click":false,"script":null) , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":32,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":7,"pressure":0.0,"pressed":false,"script":null) ] } attack1={ "deadzone": 0.5, "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"pressed":false,"double_click":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":5,"axis_value":1.0,"script":null) ] } attack2={ "deadzone": 0.5, "events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":2,"pressed":false,"double_click":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) ] } equip={ @@ -100,6 +105,7 @@ equip={ interact={ "deadzone": 0.5, "events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":70,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":2,"pressure":0.0,"pressed":false,"script":null) ] } equip_1={ @@ -146,6 +152,26 @@ right={ , Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) ] } +look_up={ +"deadzone": 0.5, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":-1.0,"script":null) +] +} +look_down={ +"deadzone": 0.5, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":4,"axis_value":1.0,"script":null) +] +} +look_left={ +"deadzone": 0.5, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) +] +} +look_right={ +"deadzone": 0.5, +"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) +] +} [internationalization]