diff --git a/DungeonShooting_Godot/scene/Main.tscn b/DungeonShooting_Godot/scene/Main.tscn index 1396064..e121019 100644 --- a/DungeonShooting_Godot/scene/Main.tscn +++ b/DungeonShooting_Godot/scene/Main.tscn @@ -1,6 +1,5 @@ -[gd_scene load_steps=6 format=3 uid="uid://lbe753cb8heb"] +[gd_scene load_steps=5 format=3 uid="uid://lbe753cb8heb"] -[ext_resource type="PackedScene" uid="uid://bvpmtfupny8iu" path="res://prefab/ui/RoomUI.tscn" id="2"] [ext_resource type="Script" path="res://src/game/GameApplication.cs" id="3"] [ext_resource type="Script" path="res://src/game/camera/GameCamera.cs" id="4_3gsi2"] @@ -21,13 +20,14 @@ shader = SubResource("1") shader_parameter/offset = Vector2(0, 0) -[node name="Main" type="Node2D" node_paths=PackedStringArray("SubViewport", "SubViewportContainer", "SceneRoot", "Ui", "GlobalNodeRoot")] +[node name="Main" type="Node2D" node_paths=PackedStringArray("SubViewport", "SubViewportContainer", "SceneRoot", "Ui", "GlobalNodeRoot", "UiCanvas")] script = ExtResource("3") SubViewport = NodePath("ViewCanvas/SubViewportContainer/SubViewport") SubViewportContainer = NodePath("ViewCanvas/SubViewportContainer") SceneRoot = NodePath("ViewCanvas/SubViewportContainer/SubViewport/SceneRoot") -Ui = NodePath("UiCanvas/RoomUI") +Ui = NodePath("") GlobalNodeRoot = NodePath("GlobalNodeRoot") +UiCanvas = NodePath("") [node name="ViewCanvas" type="CanvasLayer" parent="."] layer = -1 @@ -60,7 +60,3 @@ script = ExtResource("4_3gsi2") [node name="GlobalNodeRoot" type="Node2D" parent="."] - -[node name="UiCanvas" type="CanvasLayer" parent="."] - -[node name="RoomUI" parent="UiCanvas" instance=ExtResource("2")] diff --git a/DungeonShooting_Godot/src/framework/ui/UiManager.cs b/DungeonShooting_Godot/src/framework/ui/UiManager.cs index 289a729..0141236 100644 --- a/DungeonShooting_Godot/src/framework/ui/UiManager.cs +++ b/DungeonShooting_Godot/src/framework/ui/UiManager.cs @@ -1,9 +1,18 @@ +using System; using Godot; +/// +/// ui管理类 +/// public static partial class UiManager { private static bool _init = false; + + private static CanvasLayer _bottomLayer; + private static CanvasLayer _middleLayer; + private static CanvasLayer _heightLayer; + private static CanvasLayer _popLayer; public static void Init() { @@ -13,11 +22,60 @@ } _init = true; + + //创建ui层 + + //Bottom + _bottomLayer = new CanvasLayer(); + _bottomLayer.Name = "BottomLayer"; + _bottomLayer.Layer = 5; + GameApplication.Instance.AddChild(_bottomLayer); + + //Middle + _middleLayer = new CanvasLayer(); + _middleLayer.Name = "MiddleLayer"; + _middleLayer.Layer = 15; + GameApplication.Instance.AddChild(_middleLayer); + + //Height + _heightLayer = new CanvasLayer(); + _heightLayer.Name = "HeightLayer"; + _heightLayer.Layer = 25; + GameApplication.Instance.AddChild(_heightLayer); + + //Pop + _popLayer = new CanvasLayer(); + _popLayer.Name = "PopLayer"; + _popLayer.Layer = 35; + GameApplication.Instance.AddChild(_popLayer); } + public static CanvasLayer GetUiLayer(UiLayer uiLayer) + { + switch (uiLayer) + { + case UiLayer.Bottom: + return _bottomLayer; + case UiLayer.Middle: + return _middleLayer; + case UiLayer.Height: + return _heightLayer; + case UiLayer.Pop: + return _popLayer; + } + + return null; + } + public static UiBase OpenUi(string resourcePath) { - return null; + var packedScene = ResourceManager.Load(resourcePath); + var uiBase = packedScene.Instantiate(); + var canvasLayer = GetUiLayer(uiBase.Layer); + canvasLayer.AddChild(uiBase); + uiBase.OnCreate(); + uiBase.OnOpen(); + return uiBase; } public static T OpenUi(string resourcePath) where T : UiBase diff --git a/DungeonShooting_Godot/src/framework/ui/UiManager_Methods.cs b/DungeonShooting_Godot/src/framework/ui/UiManager_Methods.cs new file mode 100644 index 0000000..1bb9e16 --- /dev/null +++ b/DungeonShooting_Godot/src/framework/ui/UiManager_Methods.cs @@ -0,0 +1,10 @@ + +using UI.RoomUI; + +public static partial class UiManager +{ + public static RoomUIPanel Open_RoomUI() + { + return OpenUi(ResourcePath.prefab_ui_RoomUI_tscn); + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index 6706301..6832282 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -27,17 +27,12 @@ /// 场景根节点 /// [Export] public Node2D SceneRoot; - - /// - /// 游戏ui对象 - /// - [Export] public RoomUIPanel Ui; - + /// /// 全局根节点 /// [Export] public Node2D GlobalNodeRoot; - + /// /// 鼠标指针 /// @@ -79,9 +74,11 @@ // 初始化鼠标 Input.MouseMode = Input.MouseModeEnum.Hidden; Cursor = ResourceManager.Load(ResourcePath.prefab_ui_Cursor_tscn).Instantiate(); - - Ui.AddChild(Cursor); + AddChild(Cursor); + //打开ui + UiManager.Open_RoomUI(); + RoomManager = ResourceManager.Load(ResourcePath.scene_Room_tscn).Instantiate(); SceneRoot.AddChild(RoomManager); } diff --git a/DungeonShooting_Godot/src/game/event/EventEnum.cs b/DungeonShooting_Godot/src/game/event/EventEnum.cs index 23d0eeb..087d79c 100644 --- a/DungeonShooting_Godot/src/game/event/EventEnum.cs +++ b/DungeonShooting_Godot/src/game/event/EventEnum.cs @@ -20,4 +20,24 @@ /// 玩家可互动对象改变, 参数为 CheckInteractiveResult /// OnPlayerChangeInteractiveItem, + /// + /// 玩家血量发生改变, 参数为玩家血量 + /// + OnPlayerHpChange, + /// + /// 玩家最大血量发生改变, 参数为玩家最大血量 + /// + OnPlayerMaxHpChange, + /// + /// 玩家护盾值发生改变, 参数为玩家护盾值 + /// + OnPlayerShieldChange, + /// + /// 玩家最大护盾值发生改变, 参数为玩家最大护盾值 + /// + OnPlayerMaxShieldChange, + /// + /// 刷新玩家手持武器纹理, 参数为 Texture2D + /// + OnPlayerRefreshWeaponTexture, } diff --git a/DungeonShooting_Godot/src/game/event/EventFactory.cs b/DungeonShooting_Godot/src/game/event/EventFactory.cs index c5904e6..61d9855 100644 --- a/DungeonShooting_Godot/src/game/event/EventFactory.cs +++ b/DungeonShooting_Godot/src/game/event/EventFactory.cs @@ -18,9 +18,9 @@ } /// - /// 清理所有监听事件 + /// 移除所有监听事件 /// - public void Clear() + public void RemoveAllEventListener() { foreach (var eventBinder in _binders) { diff --git a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs index db9fd97..c837b6c 100644 --- a/DungeonShooting_Godot/src/game/manager/ResourcePath.cs +++ b/DungeonShooting_Godot/src/game/manager/ResourcePath.cs @@ -17,8 +17,6 @@ public const string prefab_test_TestActivity_tscn = "res://prefab/test/TestActivity.tscn"; public const string prefab_ui_Cursor_tscn = "res://prefab/ui/Cursor.tscn"; public const string prefab_ui_RoomUI_tscn = "res://prefab/ui/RoomUI.tscn"; - public const string prefab_ui_bar_InteractiveTipBar_tscn = "res://prefab/ui/bar/InteractiveTipBar.tscn"; - public const string prefab_ui_bar_ReloadBar_tscn = "res://prefab/ui/bar/ReloadBar.tscn"; public const string prefab_weapon_Knife_tscn = "res://prefab/weapon/Knife.tscn"; public const string prefab_weapon_Weapon_tscn = "res://prefab/weapon/Weapon.tscn"; public const string prefab_weapon_bullet_Bullet_tscn = "res://prefab/weapon/bullet/Bullet.tscn"; @@ -26,6 +24,7 @@ public const string resource_effects_Circle_png = "res://resource/effects/Circle.png"; public const string resource_effects_Collision_png = "res://resource/effects/Collision.png"; public const string resource_effects_debug_arrows_png = "res://resource/effects/debug_arrows.png"; + public const string resource_effects_Explosion_png = "res://resource/effects/Explosion.png"; public const string resource_effects_Hit_tres = "res://resource/effects/Hit.tres"; public const string resource_effects_KnifeHit1_tres = "res://resource/effects/KnifeHit1.tres"; public const string resource_effects_ShotFire_png = "res://resource/effects/ShotFire.png"; diff --git a/DungeonShooting_Godot/src/game/role/Player.cs b/DungeonShooting_Godot/src/game/role/Player.cs index e51ea42..a2c4dde 100644 --- a/DungeonShooting_Godot/src/game/role/Player.cs +++ b/DungeonShooting_Godot/src/game/role/Player.cs @@ -38,7 +38,7 @@ // MainCamera.Main.ResetSmoothing(); // remoteTransform.RemotePath = remoteTransform.GetPathTo(MainCamera.Main); - RefreshGunTexture(); + RefreshWeaponTexture(); MaxHp = 50; Hp = 50; @@ -87,7 +87,7 @@ var item = TriggerInteractive(); if (item != null) { - RefreshGunTexture(); + RefreshWeaponTexture(); } } else if (Input.IsActionJustPressed("reload")) //换弹 @@ -98,8 +98,6 @@ { Attack(); } - //刷新显示的弹药剩余量 - RefreshGunAmmunition(); } protected override void PhysicsProcess(float delta) @@ -113,25 +111,25 @@ public override void ExchangeNext() { base.ExchangeNext(); - RefreshGunTexture(); + RefreshWeaponTexture(); } public override void ExchangePrev() { base.ExchangePrev(); - RefreshGunTexture(); + RefreshWeaponTexture(); } public override void ThrowWeapon(int index) { base.ThrowWeapon(index); - RefreshGunTexture(); + RefreshWeaponTexture(); } public override void ThrowWeapon() { base.ThrowWeapon(); - RefreshGunTexture(); + RefreshWeaponTexture(); } public override bool PickUpWeapon(Weapon weapon, bool exchange = true) @@ -139,19 +137,21 @@ var v = base.PickUpWeapon(weapon, exchange); if (v) { - RefreshGunTexture(); + RefreshWeaponTexture(); } return v; } protected override void OnChangeHp(int hp) { - GameApplication.Instance.Ui.SetHp(hp); + //GameApplication.Instance.Ui.SetHp(hp); + EventManager.EmitEvent(EventEnum.OnPlayerHpChange, hp); } protected override void OnChangeMaxHp(int maxHp) { - GameApplication.Instance.Ui.SetMaxHp(maxHp); + //GameApplication.Instance.Ui.SetMaxHp(maxHp); + EventManager.EmitEvent(EventEnum.OnPlayerMaxHpChange, maxHp); } protected override void ChangeInteractiveItem(CheckInteractiveResult result) @@ -162,40 +162,22 @@ protected override void OnChangeShield(int shield) { - GameApplication.Instance.Ui.SetShield(shield); + //GameApplication.Instance.Ui.SetShield(shield); + EventManager.EmitEvent(EventEnum.OnPlayerShieldChange, shield); } protected override void OnChangeMaxShield(int maxShield) { - GameApplication.Instance.Ui.SetMaxShield(maxShield); + //GameApplication.Instance.Ui.SetMaxShield(maxShield); + EventManager.EmitEvent(EventEnum.OnPlayerMaxShieldChange, maxShield); } /// /// 刷新 ui 上手持的物体 /// - private void RefreshGunTexture() + private void RefreshWeaponTexture() { - var gun = Holster.ActiveWeapon; - if (gun != null) - { - GameApplication.Instance.Ui.SetGunTexture(gun.GetDefaultTexture()); - } - else - { - GameApplication.Instance.Ui.SetGunTexture(null); - } - } - - /// - /// 刷新 ui 上显示的弹药量 - /// - private void RefreshGunAmmunition() - { - var gun = Holster.ActiveWeapon; - if (gun != null) - { - GameApplication.Instance.Ui.SetAmmunition(gun.CurrAmmo, gun.ResidueAmmo); - } + EventManager.EmitEvent(EventEnum.OnPlayerRefreshWeaponTexture, Holster.ActiveWeapon?.GetDefaultTexture()); } //处理角色移动的输入 diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs index 88d627b..e619cf6 100644 --- a/DungeonShooting_Godot/src/game/role/Role.cs +++ b/DungeonShooting_Godot/src/game/role/Role.cs @@ -36,13 +36,13 @@ /// public uint AttackLayer { get; set; } = PhysicsLayer.Wall; - /// - /// 携带的道具包裹 - /// - public List PropsPack { get; } = new List(); + // /// + // /// 携带的道具包裹 + // /// + // public List PropsPack { get; } = new List(); /// - /// 角色携带的枪套 + /// 角色携带的武器袋 /// public Holster Holster { get; private set; } diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/GunBar.cs b/DungeonShooting_Godot/src/game/ui/roomUI/GunBar.cs new file mode 100644 index 0000000..4022dd2 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/roomUI/GunBar.cs @@ -0,0 +1,82 @@ +using Godot; + +namespace UI.RoomUI; + +public class GunBar +{ + private RoomUI.UiNode15_GunBar _gunBar; + private EventBinder _binder; + + private int _prevAmmo = -1; + private int _prevResidue = -1; + + public GunBar(RoomUI.UiNode15_GunBar gunBar) + { + _gunBar = gunBar; + } + + public void OnOpen() + { + _binder = EventManager.AddEventListener(EventEnum.OnPlayerRefreshWeaponTexture, OnPlayerRefreshWeaponTexture); + } + + public void OnClose() + { + _binder.RemoveEventListener(); + } + + public void Process(float delta) + { + var weapon = Player.Current.Holster.ActiveWeapon; + if (weapon != null) + { + SetWeaponAmmunition(weapon.CurrAmmo, weapon.ResidueAmmo); + } + } + + /// + /// 设置显示在 ui 上武器的纹理 + /// + /// 纹理 + public void SetWeaponTexture(Texture2D gun) + { + if (gun != null) + { + _gunBar.L_GunSprite.Instance.Texture = gun; + _gunBar.L_GunSprite.Instance.Visible = true; + _gunBar.L_BulletText.Instance.Visible = true; + } + else + { + _gunBar.L_GunSprite.Instance.Visible = false; + _gunBar.L_BulletText.Instance.Visible = false; + } + } + + /// + /// 设置弹药数据 + /// + /// 当前弹夹弹药量 + /// 剩余弹药总数 + public void SetWeaponAmmunition(int curr, int total) + { + if (curr != _prevAmmo || total != _prevResidue) + { + _gunBar.L_BulletText.Instance.Text = curr + " / " + total; + _prevAmmo = curr; + _prevResidue = total; + } + } + + private void OnPlayerRefreshWeaponTexture(object o) + { + if (o == null) + { + SetWeaponTexture(null); + } + else + { + SetWeaponTexture((Texture2D)o); + } + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/HealthBar.cs b/DungeonShooting_Godot/src/game/ui/roomUI/HealthBar.cs new file mode 100644 index 0000000..0e387a7 --- /dev/null +++ b/DungeonShooting_Godot/src/game/ui/roomUI/HealthBar.cs @@ -0,0 +1,104 @@ +using System; +using Godot; + +namespace UI.RoomUI; + +public class HealthBar +{ + private RoomUI.UiNode9_HealthBar _healthBar; + // 当前血量 + private int _hp; + // 最大血量 + private int _maxHp; + // 当前护盾值 + private int _shield; + // 最大护盾值 + private int _maxShield; + + private EventFactory _eventFactory; + + public HealthBar(RoomUI.UiNode9_HealthBar healthBar) + { + _healthBar = healthBar; + } + + public void OnOpen() + { + _eventFactory = EventManager.CreateEventFactory(); + _eventFactory.AddEventListener(EventEnum.OnPlayerHpChange, OnPlayerHpChange); + _eventFactory.AddEventListener(EventEnum.OnPlayerMaxHpChange, OnPlayerMaxHpChange); + _eventFactory.AddEventListener(EventEnum.OnPlayerShieldChange, OnPlayerShieldChange); + _eventFactory.AddEventListener(EventEnum.OnPlayerMaxShieldChange, OnPlayerMaxShieldChange); + } + + public void OnClose() + { + _eventFactory.RemoveAllEventListener(); + } + + /// + /// 设置最大血量 + /// + public void SetMaxHp(int maxHp) + { + _maxHp = Mathf.Max(maxHp, 0); + _healthBar.L_HpSlot.Instance.Size = new Vector2(maxHp + 3, _healthBar.L_HpSlot.Instance.Size.Y); + if (_hp > maxHp) + { + SetHp(maxHp); + } + } + + /// + /// 设置最大护盾值 + /// + public void SetMaxShield(int maxShield) + { + _maxShield = Mathf.Max(maxShield, 0); + _healthBar.L_ShieldSlot.Instance.Size = new Vector2(maxShield + 2, _healthBar.L_ShieldSlot.Instance.Size.Y); + if (_shield > _maxShield) + { + SetShield(maxShield); + } + } + + /// + /// 设置当前血量 + /// + public void SetHp(int hp) + { + _hp = Mathf.Clamp(hp, 0, _maxHp); + var textureRect = _healthBar.L_HpSlot.L_HpBar.Instance; + textureRect.Size = new Vector2(hp, textureRect.Size.Y); + } + + /// + /// 设置护盾值 + /// + public void SetShield(int shield) + { + _shield = Mathf.Clamp(shield, 0, _maxShield); + var textureRect = _healthBar.L_ShieldSlot.L_ShieldBar.Instance; + textureRect.Size = new Vector2(shield, textureRect.Size.Y); + } + + private void OnPlayerHpChange(object o) + { + SetHp(Convert.ToInt32(o)); + } + + private void OnPlayerMaxHpChange(object o) + { + SetMaxHp(Convert.ToInt32(o)); + } + + private void OnPlayerShieldChange(object o) + { + SetShield(Convert.ToInt32(o)); + } + + private void OnPlayerMaxShieldChange(object o) + { + SetMaxShield(Convert.ToInt32(o)); + } +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs index 9b3daba..e0d0e6a 100644 --- a/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs +++ b/DungeonShooting_Godot/src/game/ui/roomUI/RoomUIPanel.cs @@ -7,128 +7,38 @@ /// public partial class RoomUIPanel : RoomUI { - /// - /// 当前血量 - /// - public int Hp { get; private set; } - /// - /// 最大血量 - /// - public int MaxHp { get; private set; } - /// - /// 当前护盾值 - /// - public int Shield { get; private set; } - /// - /// 最大护盾值 - /// - public int MaxShield { get; private set; } - private ReloadBar _reloadBar; private InteractiveTipBar _interactiveTipBar; + private HealthBar _healthBar; + private GunBar _gunBar; + + public override void OnCreate() + { + //Generator.UiGenerator.GenerateUi(this, "src/game/ui/roomUI/RoomUI.cs"); + _reloadBar = new ReloadBar(L_ReloadBar); + _interactiveTipBar = new InteractiveTipBar(L_InteractiveTipBar); + _healthBar = new HealthBar(L_Control.L_HealthBar); + _gunBar = new GunBar(L_Control.L_GunBar); + } public override void OnOpen(params object[] args) { _reloadBar.OnOpen(); _interactiveTipBar.OnOpen(); + _healthBar.OnOpen(); + _gunBar.OnOpen(); } public override void OnClose() { _reloadBar.OnClose(); _interactiveTipBar.OnClose(); + _healthBar.OnClose(); + _gunBar.OnClose(); } - public override void _Ready() + public override void _Process(double delta) { - //Generator.UiGenerator.GenerateUi(this, "src/game/ui/roomUI/RoomUI.cs"); - _reloadBar = new ReloadBar(L_ReloadBar); - _interactiveTipBar = new InteractiveTipBar(L_InteractiveTipBar); - - OnOpen(); + _gunBar.Process((float) delta); } - - /// - /// 设置最大血量 - /// - public void SetMaxHp(int maxHp) - { - MaxHp = Mathf.Max(maxHp, 0); - L_Control.L_HealthBar.L_HpSlot.Instance.Size = new Vector2(maxHp + 3, L_Control.L_HealthBar.L_HpSlot.Instance.Size.Y); - if (Hp > maxHp) - { - SetHp(maxHp); - } - } - - /// - /// 设置最大护盾值 - /// - public void SetMaxShield(int maxShield) - { - MaxShield = Mathf.Max(maxShield, 0); - L_Control.L_HealthBar.L_ShieldSlot.Instance.Size = new Vector2(maxShield + 2, L_Control.L_HealthBar.L_ShieldSlot.Instance.Size.Y); - if (Shield > MaxShield) - { - SetShield(maxShield); - } - } - - /// - /// 设置当前血量 - /// - public void SetHp(int hp) - { - Hp = Mathf.Clamp(hp, 0, MaxHp); - var textureRect = L_Control.L_HealthBar.L_HpSlot.L_HpBar.Instance; - textureRect.Size = new Vector2(hp, textureRect.Size.Y); - } - - /// - /// 设置护盾值 - /// - public void SetShield(int shield) - { - Shield = Mathf.Clamp(shield, 0, MaxShield); - var textureRect = L_Control.L_HealthBar.L_ShieldSlot.L_ShieldBar.Instance; - textureRect.Size = new Vector2(shield, textureRect.Size.Y); - } - - /// - /// 玩家受到伤害 - /// - public void Hit(int num) - { - - } - - /// - /// 设置显示在 ui 上的枪的纹理 - /// - /// 纹理 - public void SetGunTexture(Texture2D gun) - { - if (gun != null) - { - L_Control.L_GunBar.L_GunSprite.Instance.Texture = gun; - L_Control.L_GunBar.L_GunSprite.Instance.Visible = true; - L_Control.L_GunBar.L_BulletText.Instance.Visible = true; - } - else - { - L_Control.L_GunBar.L_GunSprite.Instance.Visible = false; - L_Control.L_GunBar.L_BulletText.Instance.Visible = false; - } - } - - /// - /// 设置弹药数据 - /// - /// 当前弹夹弹药量 - /// 剩余弹药总数 - public void SetAmmunition(int curr, int total) - { - L_Control.L_GunBar.L_BulletText.Instance.Text = curr + " / " + total; - } - } \ No newline at end of file