diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs index 92b23f9..a23a086 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject.cs @@ -5,7 +5,10 @@ using Godot; /// -/// 房间内活动物体基类, 所有物体都必须继承该类 +/// 房间内活动物体基类, 所有物体都必须继承该类, +/// ActivityObject 使用的时候代码和场景分离的设计模式, 所以创建时必须指定模板场景路径, 这样做的好处是一个模板场景可以用在多个代码类上, 同样一个代码类也可以指定不同的目模板场景, +/// ActivityObject 子类实例化请不要直接使用 new, 而用该在类上标上 [RegisterActivity(id, prefabPath)], +/// ActivityObject 类会自动扫描并注册物体, 然后使用而是使用 ActivityObject.Create(id) 来创建实例 /// public abstract partial class ActivityObject : CharacterBody2D { @@ -98,8 +101,9 @@ private static long _instanceIndex = 0; - private void _InitNode(string scenePath) + private void _InitNode(string itemId, string scenePath) { + ItemId = itemId; Name = GetType().Name + (_instanceIndex++); //加载预制体 var tempPrefab = ResourceManager.Load(scenePath); diff --git a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs index 111bea6..ef9be6e 100644 --- a/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs +++ b/DungeonShooting_Godot/src/framework/activity/ActivityObject_Register.cs @@ -7,6 +7,7 @@ { private static bool _initState = false; + //物体注册数据 private class RegisterActivityData { public RegisterActivityData(RegisterActivity registerActivity, Func callBack) @@ -19,8 +20,12 @@ public Func CallBack; } + //所有注册物体集合 private static readonly Dictionary _activityRegisterMap = new(); + /// + /// 初始化调用, 开始扫描当前程序集, 并自动注册 ActivityObject 物体 + /// public static void Init() { if (_initState) @@ -29,10 +34,15 @@ } _initState = true; - + //扫描当前程序集 ScannerFromAssembly(typeof(ActivityObject).Assembly); } + /// + /// 扫描指定程序集, 自动注册带有 RegisterActivity 特性的类 + /// + /// + /// public static void ScannerFromAssembly(Assembly assembly) { var types = assembly.GetTypes(); @@ -44,21 +54,26 @@ { if (!typeof(ActivityObject).IsAssignableFrom(type)) { + //不是继承自 ActivityObject throw new Exception($"The registered object '{type.FullName}' does not inherit the class ActivityObject."); } else if (type.IsAbstract) { + //不能加到抽象类上 throw new Exception($"'RegisterActivity' cannot be used on abstract class '{type.FullName}'."); } var attrs = (RegisterActivity[])attribute; foreach (var att in attrs) { + //注册操作 if (_activityRegisterMap.ContainsKey(att.Id)) { throw new Exception($"Object ID: '{att.Id}' is already registered"); } - var registerCallback = att.RegisterInstantiationCallback(type); - _activityRegisterMap.Add(att.Id, new RegisterActivityData(att, registerCallback)); + _activityRegisterMap.Add(att.Id, new RegisterActivityData(att, () => + { + return (ActivityObject)Activator.CreateInstance(type); + })); } } } @@ -67,13 +82,29 @@ /// /// 通过 ItemId 实例化 ActivityObject 对象 /// - public static T Create(string itemId) where T : ActivityObject + public static ActivityObject Create(string itemId) { if (_activityRegisterMap.TryGetValue(itemId, out var item)) { var instance = item.CallBack(); - instance._InitNode(item.RegisterActivity.PrefabPath); + instance._InitNode(item.RegisterActivity.Id, item.RegisterActivity.PrefabPath); + item.RegisterActivity.CustomHandler(instance); + return instance; } return null; } + + /// + /// 通过 ItemId 实例化 ActivityObject 对象 + /// + public static T Create(string itemId) where T : ActivityObject + { + var instance = Create(itemId); + if (instance != null) + { + return (T)instance; + } + + return null; + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs b/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs index 9b05eb8..f5f1a03 100644 --- a/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs +++ b/DungeonShooting_Godot/src/framework/activity/RegisterActivity.cs @@ -1,7 +1,9 @@ using System; -using System.Diagnostics.CodeAnalysis; +/// +/// 用在 ActivityObject 子类上, 用于注册游戏中的物体, 一个类可以添加多个 [RegisterActivity] 特性, ActivityObject 会自动扫描并注册物体 +/// [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] public class RegisterActivity : Attribute { @@ -11,7 +13,7 @@ public string Id { get; } /// - /// 模板Prefab的路径 + /// 模板 Prefab 的路径 /// public string PrefabPath { get; protected set; } @@ -21,9 +23,10 @@ PrefabPath = prefabPath; } - - public virtual Func RegisterInstantiationCallback(Type type) + /// + /// 该函数在物体实例化后调用, 可用于一些自定义操作, 参数为实例对象 + /// + public virtual void CustomHandler(ActivityObject instance) { - return () => { return (ActivityObject)Activator.CreateInstance(type); }; } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/GameApplication.cs b/DungeonShooting_Godot/src/game/GameApplication.cs index c3df18e..a370d06 100644 --- a/DungeonShooting_Godot/src/game/GameApplication.cs +++ b/DungeonShooting_Godot/src/game/GameApplication.cs @@ -67,8 +67,8 @@ InitRoomConfig(); - //扫描并注册当前程序集下的武器 - WeaponManager.RegisterWeaponFromAssembly(GetType().Assembly); + //初始化 ActivityObject + ActivityObject.Init(); } public override void _EnterTree() diff --git a/DungeonShooting_Godot/src/game/item/package/Holster.cs b/DungeonShooting_Godot/src/game/item/package/Holster.cs index 48bddfe..a971b08 100644 --- a/DungeonShooting_Godot/src/game/item/package/Holster.cs +++ b/DungeonShooting_Godot/src/game/item/package/Holster.cs @@ -124,7 +124,7 @@ for (int i = 0; i < SlotList.Length; i++) { var item = SlotList[i]; - if (item.Weapon != null && item.Weapon.TypeId == id) + if (item.Weapon != null && item.Weapon.ItemId == id) { return i; } diff --git a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponFunction.cs b/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponFunction.cs deleted file mode 100644 index 1796a95..0000000 --- a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponFunction.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -/// -/// 用作静态函数上, 用于注册武器, 函数必须返回一个 Weapon 对象, 且参数为 string id, -/// 那么它看起来应该像这样: static Weapon Method(string id); -/// -[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] -public class RegisterWeaponFunction : Attribute -{ - public string Id { get; private set; } - - public RegisterWeaponFunction(string id) - { - Id = id; - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponOld.cs b/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponOld.cs deleted file mode 100644 index 026bc53..0000000 --- a/DungeonShooting_Godot/src/game/item/weapon/RegisterWeaponOld.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -/// -/// 用作 Weapon 子类上, 用于注册武器, 允许同时存在多个 RegisterWeapon 特性 -/// -[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] -public class RegisterWeaponOld : Attribute -{ - public string Id { get; private set; } - public Type AttributeType { get; private set; } - - public RegisterWeaponOld(string id) - { - Id = id; - } - - public RegisterWeaponOld(string id, Type attributeType) - { - Id = id; - AttributeType = attributeType; - } -} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs index 3988260..7c806d4 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/Weapon.cs @@ -13,11 +13,6 @@ public static readonly HashSet UnclaimedWeapons = new HashSet(); /// - /// 武器的类型 id - /// - public string TypeId { get; } - - /// /// 开火回调事件 /// public event Action FireEvent; @@ -169,13 +164,10 @@ private float _currBacklashLength = 0; /// - /// 根据属性创建一把武器 + /// 初始化武器属性 /// - /// 武器的类型id - /// 属性 - public Weapon(string typeId, WeaponAttribute attribute) : base(attribute.WeaponPrefab) + public void InitWeapon(WeaponAttribute attribute) { - TypeId = typeId; _originWeaponAttribute = attribute; _weaponAttribute = attribute; @@ -195,14 +187,14 @@ if (Attribute.AmmoCapacity > Attribute.MaxAmmoCapacity) { Attribute.AmmoCapacity = Attribute.MaxAmmoCapacity; - GD.PrintErr("弹夹的容量不能超过弹药上限, 武器id: " + typeId); + GD.PrintErr("弹夹的容量不能超过弹药上限, 武器id: " + ItemId); } //弹药量 CurrAmmo = Attribute.AmmoCapacity; //剩余弹药量 ResidueAmmo = Mathf.Min(Attribute.StandbyAmmoCapacity + CurrAmmo, Attribute.MaxAmmoCapacity) - CurrAmmo; } - + /// /// 单次开火时调用的函数 /// @@ -805,7 +797,7 @@ { var masterWeapon = roleMaster.Holster.ActiveWeapon; //查找是否有同类型武器 - var index = roleMaster.Holster.FindWeapon(TypeId); + var index = roleMaster.Holster.FindWeapon(ItemId); if (index != -1) //如果有这个武器 { if (CurrAmmo + ResidueAmmo != 0) //子弹不为空 @@ -852,7 +844,7 @@ { var holster = roleMaster.Holster; //查找是否有同类型武器 - var index = holster.FindWeapon(TypeId); + var index = holster.FindWeapon(ItemId); if (index != -1) //如果有这个武器 { if (CurrAmmo + ResidueAmmo == 0) //没有子弹了 diff --git a/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs b/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs index 0f4e3c6..6c245d3 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/WeaponAttribute.cs @@ -225,9 +225,8 @@ /// public float AiTargetLockingTime = 0; + /// + /// Ai 使用该武器时的武器数据, 设置该字段, 可让同一把武器在敌人和玩家手上有不同属性 + /// public WeaponAttribute AiUseAttribute; - - public AiFireCallback OnAiFireCallback; - - public delegate void AiFireCallback(Enemy enemy, Weapon weapon); } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs b/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs deleted file mode 100644 index b084ddb..0000000 --- a/DungeonShooting_Godot/src/game/item/weapon/WeaponManager.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Reflection; -using System; -using System.Collections.Generic; -using Godot; - -/// -/// 武器管理类, 负责武器注册和创建 -/// -public static class WeaponManager -{ - private static Dictionary> registerData = new Dictionary>(); - - /// - /// 从一个指定的程序集中扫描并注册武器对象 - /// - /// 数据集 - public static void RegisterWeaponFromAssembly(Assembly assembly) - { - var types = assembly.GetTypes(); - foreach (var type in types) - { - //注册类 - Attribute[] attribute = Attribute.GetCustomAttributes(type, typeof(RegisterWeaponOld), false); - if (attribute != null && attribute.Length > 0) - { - if (!typeof(Weapon).IsAssignableFrom(type)) - { - throw new Exception($"注册武器类'{type.FullName}'没有继承类'Weapon'!"); - } - var atts = (RegisterWeaponOld[])attribute; - foreach (var att in atts) - { - //注册类 - if (att.AttributeType == null) //没有指定属性类型 - { - RegisterWeapon(att.Id, () => - { - return Activator.CreateInstance(type, att.Id, new WeaponAttribute()) as Weapon; - }); - } - else - { - if (!typeof(WeaponAttribute).IsAssignableFrom(att.AttributeType)) - { - throw new Exception($"注册武器类'{type.FullName}'标注的特性中参数'AttributeType'类型没有继承'WeaponAttribute'!"); - } - RegisterWeapon(att.Id, () => - { - return Activator.CreateInstance(type, att.Id, Activator.CreateInstance(att.AttributeType)) as Weapon; - }); - } - } - } - - //注册函数 - MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); - foreach (var method in methods) - { - Attribute mAttribute; - // - if ((mAttribute = Attribute.GetCustomAttribute(method, typeof(RegisterWeaponFunction), false)) != null) - { - if (!typeof(Weapon).IsAssignableFrom(method.ReturnType)) //返回值类型不是 Weapon - { - throw new Exception($"注册武器函数'{method.DeclaringType.FullName}.{method.Name}'返回值类型不为'Weapon'!"); - } - var args = method.GetParameters(); - if (args == null || args.Length != 1 || args[0].ParameterType != typeof(string)) //参数类型不正确 - { - throw new Exception($"注册武器函数'{method.DeclaringType.FullName}.{method.Name}'参数不满足(string id)类型"); - } - var att = (RegisterWeaponFunction)mAttribute; - //注册函数 - RegisterWeapon(att.Id, () => - { - return method.Invoke(null, new object[] { att.Id }) as Weapon; - }); - } - } - } - } - - /// - /// 注册当个武器对象 - /// - /// 武器唯一id, 该id不能重复 - /// 获取武器时的回调函数, 函数返回武器对象 - public static void RegisterWeapon(string id, Func callBack) - { - if (registerData.ContainsKey(id)) - { - throw new Exception($"武器id: '{id} 已经被注册!'"); - } - registerData.Add(id, callBack); - } - - /// - /// 根据武器唯一id获取 - /// - /// 武器id - public static Weapon GetGun(string id) - { - if (registerData.TryGetValue(id, out var callback)) - { - return callback(); - } - throw new Exception($"当前武器'{id}未被注册'"); - } - - /// - /// 根据武器唯一id获取 - /// - /// 武器id - public static T GetGun(string id) where T : Weapon - { - return (T)GetGun(id); - } -} diff --git a/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs b/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs index cac55b9..b475c01 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/bullet/Bullet.cs @@ -3,12 +3,13 @@ /// /// 子弹类 /// +[RegisterActivity(ActivityIdPrefix.Bullet + "0001", ResourcePath.prefab_weapon_bullet_Bullet_tscn)] public partial class Bullet : ActivityObject { /// /// 碰撞区域 /// - public Area2D CollisionArea { get; } + public Area2D CollisionArea { get; private set; } // 最大飞行距离 private float MaxDistance; @@ -19,8 +20,7 @@ //当前子弹已经飞行的距离 private float CurrFlyDistance = 0; - public Bullet(string scenePath, float speed, float maxDistance, Vector2 position, float rotation, uint targetLayer) : - base(scenePath) + public void Init(float speed, float maxDistance, Vector2 position, float rotation, uint targetLayer) { CollisionArea = GetNode("CollisionArea"); CollisionArea.CollisionMask = targetLayer; diff --git a/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs b/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs index 181584e..6ee6ea3 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/bullet/RegisterWeapon.cs @@ -1,6 +1,9 @@ using System; +/// +/// 注册武器 +/// public class RegisterWeapon : RegisterActivity { public WeaponAttribute WeaponAttribute { get; } @@ -10,4 +13,12 @@ WeaponAttribute = (WeaponAttribute)Activator.CreateInstance(attribute); if (WeaponAttribute != null) PrefabPath = WeaponAttribute.WeaponPrefab; } + + public override void CustomHandler(ActivityObject instance) + { + if (instance is Weapon weapon) + { + weapon.InitWeapon(WeaponAttribute.Clone()); + } + } } \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs index a003ae9..89060d4 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Gun.cs @@ -3,9 +3,8 @@ /// /// 普通的枪 /// -[RegisterWeaponOld("1001", typeof(Gun.RifleAttribute))] -[RegisterWeaponOld("1003", typeof(Gun.PistolAttribute))] -[RegisterWeapon("1003", typeof(PistolAttribute))] +[RegisterWeapon(ActivityIdPrefix.Weapon + "0001", typeof(RifleAttribute))] +[RegisterWeapon(ActivityIdPrefix.Weapon + "0003", typeof(PistolAttribute))] public partial class Gun : Weapon { //步枪属性数据 @@ -96,11 +95,7 @@ AiUseAttribute.TriggerInterval = 2f; } } - - public Gun(string typeId, WeaponAttribute attribute): base(typeId, attribute) - { - } - + protected override void OnFire() { //创建一个弹壳 @@ -109,7 +104,7 @@ var xf = Utils.RandomRangeInt(20, 60); var yf = Utils.RandomRangeInt(60, 120); var rotate = Utils.RandomRangeInt(-720, 720); - var shell = new ShellCase(); + var shell = ActivityObject.Create(ActivityIdPrefix.Shell + "0001");; shell.Throw(new Vector2(10, 5), Master.GlobalPosition, startHeight, direction, xf, yf, rotate, true); if (Master == GameApplication.Instance.RoomManager.Player) @@ -132,9 +127,9 @@ protected override void OnShoot(float fireRotation) { //创建子弹 - //CreateBullet(BulletPack, FirePoint.GlobalPosition, fireRotation); - var bullet = new Bullet( - ResourcePath.prefab_weapon_bullet_Bullet_tscn, + const string bulletId = ActivityIdPrefix.Bullet + "0001"; + var bullet = ActivityObject.Create(bulletId); + bullet.Init( 350, Utils.RandomRangeFloat(Attribute.MinDistance, Attribute.MaxDistance), FirePoint.GlobalPosition, diff --git a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs index 24ac9b8..2d5576d 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/gun/Shotgun.cs @@ -1,6 +1,6 @@ using Godot; -[RegisterWeaponOld("1002", typeof(Shotgun.ShotgunAttribute))] +[RegisterWeapon(ActivityIdPrefix.Weapon + "0002", typeof(ShotgunAttribute))] public partial class Shotgun : Weapon { @@ -54,8 +54,9 @@ /// public PackedScene ShellPack; - public Shotgun(string typeId, WeaponAttribute attribute) : base(typeId, attribute) + public override void _Ready() { + base._Ready(); ShellPack = ResourceManager.Load(ResourcePath.prefab_weapon_shell_ShellCase_tscn); } @@ -68,7 +69,7 @@ var xf = Utils.RandomRangeInt(20, 60); var yf = Utils.RandomRangeInt(60, 120); var rotate = Utils.RandomRangeInt(-720, 720); - var shell = new ShellCase(); + var shell = ActivityObject.Create(ActivityIdPrefix.Shell + "0001");; shell.Throw(new Vector2(5, 10), startPos, startHeight, direction, xf, yf, rotate, true); if (Master == GameApplication.Instance.RoomManager.Player) @@ -91,8 +92,9 @@ protected override void OnShoot(float fireRotation) { //创建子弹 - var bullet = new Bullet( - ResourcePath.prefab_weapon_bullet_Bullet_tscn, + const string bulletId = ActivityIdPrefix.Bullet + "0001"; + var bullet = ActivityObject.Create(bulletId); + bullet.Init( Utils.RandomRangeInt(280, 380), Utils.RandomRangeFloat(Attribute.MinDistance, Attribute.MaxDistance), FirePoint.GlobalPosition, diff --git a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs index 1225928..5d329ac 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/knife/Knife.cs @@ -1,7 +1,7 @@ using Godot; -[RegisterWeaponOld("1004", typeof(KnifeAttribute))] +[RegisterWeapon(ActivityIdPrefix.Weapon + "0004", typeof(KnifeAttribute))] public partial class Knife : Weapon { private class KnifeAttribute : WeaponAttribute @@ -35,11 +35,12 @@ } private Area2D _hitArea; - private int _attackIndex = 0; - public Knife(string typeId, WeaponAttribute attribute) : base(typeId, attribute) + public override void _Ready() { + base._Ready(); + _hitArea = GetNode("HitArea"); _hitArea.Monitoring = false; _hitArea.Monitorable = false; diff --git a/DungeonShooting_Godot/src/game/item/weapon/shell/ShellCase.cs b/DungeonShooting_Godot/src/game/item/weapon/shell/ShellCase.cs index f222a8c..ef60e6b 100644 --- a/DungeonShooting_Godot/src/game/item/weapon/shell/ShellCase.cs +++ b/DungeonShooting_Godot/src/game/item/weapon/shell/ShellCase.cs @@ -4,9 +4,10 @@ /// /// 弹壳类 /// +[RegisterActivity(ActivityIdPrefix.Shell + "0001", ResourcePath.prefab_weapon_shell_ShellCase_tscn)] public partial class ShellCase : ActivityObject { - public ShellCase() : base(ResourcePath.prefab_weapon_shell_ShellCase_tscn) + public override void _Ready() { ShadowOffset = new Vector2(0, 1); } diff --git a/DungeonShooting_Godot/src/game/manager/ActivityIdPrefix.cs b/DungeonShooting_Godot/src/game/manager/ActivityIdPrefix.cs new file mode 100644 index 0000000..3523fcf --- /dev/null +++ b/DungeonShooting_Godot/src/game/manager/ActivityIdPrefix.cs @@ -0,0 +1,29 @@ + +//Activity注册类id前缀 +public static class ActivityIdPrefix +{ + /// + /// 测试单位 + /// + public const string Test = "test"; + /// + /// 角色 + /// + public const string Role = "role"; + /// + /// 敌人 + /// + public const string Enemy = "enemy"; + /// + /// 武器 + /// + public const string Weapon = "weapon"; + /// + /// 子弹 + /// + public const string Bullet = "bullet"; + /// + /// 弹壳 + /// + public const string Shell = "shell"; +} \ No newline at end of file diff --git a/DungeonShooting_Godot/src/game/role/Player.cs b/DungeonShooting_Godot/src/game/role/Player.cs index 7e122e5..e4d9b24 100644 --- a/DungeonShooting_Godot/src/game/role/Player.cs +++ b/DungeonShooting_Godot/src/game/role/Player.cs @@ -1,10 +1,10 @@ -using System.Collections; using Godot; /// /// 玩家角色基类, 所有角色都必须继承该类 /// +[RegisterActivity(ActivityIdPrefix.Role + "0001", ResourcePath.prefab_role_Player_tscn)] public partial class Player : Role { /// @@ -21,20 +21,16 @@ /// 移动摩擦力 /// public float Friction { get; set; } = 800f; - - public Player(): base(ResourcePath.prefab_role_Player_tscn) + + public override void _Ready() { + base._Ready(); + AttackLayer = PhysicsLayer.Wall | PhysicsLayer.Props | PhysicsLayer.Enemy; Camp = CampEnum.Camp1; Holster.SlotList[2].Enable = true; Holster.SlotList[3].Enable = true; - } - - public override void _Ready() - { - base._Ready(); - //让相机跟随玩家 // var remoteTransform = new RemoteTransform2D(); // AddChild(remoteTransform); diff --git a/DungeonShooting_Godot/src/game/role/Role.cs b/DungeonShooting_Godot/src/game/role/Role.cs index 3422540..70f1df6 100644 --- a/DungeonShooting_Godot/src/game/role/Role.cs +++ b/DungeonShooting_Godot/src/game/role/Role.cs @@ -209,14 +209,9 @@ protected virtual void OnDie() { } - - public Role() : this(ResourcePath.prefab_role_Role_tscn) - { - } public override void _Ready() { - base._Ready(); Holster = new Holster(this); _startScale = Scale; MountPoint = GetNode("MountPoint"); diff --git a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs index f0eb813..a46747e 100644 --- a/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs +++ b/DungeonShooting_Godot/src/game/role/enemy/Enemy.cs @@ -17,7 +17,7 @@ /// /// 基础敌人 /// -[RegisterActivity("1001", ResourcePath.prefab_role_Enemy_tscn)] +[RegisterActivity(ActivityIdPrefix.Enemy + "0001", ResourcePath.prefab_role_Enemy_tscn)] public partial class Enemy : Role { /// @@ -35,7 +35,7 @@ /// /// 敌人身上的状态机控制器 /// - public StateController StateController { get; } + public StateController StateController { get; private set; } /// /// 视野半径, 单位像素, 发现玩家后改视野范围可以穿墙 @@ -55,25 +55,26 @@ /// /// 视野检测射线, 朝玩家打射线, 检测是否碰到墙 /// - public RayCast2D ViewRay { get; } + public RayCast2D ViewRay { get; private set; } /// /// 导航代理 /// - public NavigationAgent2D NavigationAgent2D { get; } + public NavigationAgent2D NavigationAgent2D { get; private set; } /// /// 导航代理中点 /// - public Marker2D NavigationPoint { get; } + public Marker2D NavigationPoint { get; private set; } //开火间隙时间 private float _enemyAttackTimer = 0; //目标在视野内的时间 private float _targetInViewTime = 0; - public Enemy() : base(ResourcePath.prefab_role_Enemy_tscn) + public override void _Ready() { + base._Ready(); IsAi = true; StateController = AddComponent>(); @@ -103,11 +104,7 @@ StateController.Register(new AiLeaveForState()); StateController.Register(new AiSurroundState()); StateController.Register(new AiFindAmmoState()); - } - - public override void _Ready() - { - base._Ready(); + //默认状态 StateController.ChangeState(AiStateEnum.AiNormal); @@ -352,7 +349,7 @@ return; } - var index = Holster.FindWeapon((we, i) => we.TypeId == weapon.TypeId); + var index = Holster.FindWeapon((we, i) => we.ItemId == weapon.ItemId); if (index != -1) //与武器袋中武器类型相同, 补充子弹 { if (!Holster.GetWeapon(index).IsAmmoFull()) diff --git a/DungeonShooting_Godot/src/game/room/RoomManager.cs b/DungeonShooting_Godot/src/game/room/RoomManager.cs index c4e5be8..01005a8 100644 --- a/DungeonShooting_Godot/src/game/room/RoomManager.cs +++ b/DungeonShooting_Godot/src/game/room/RoomManager.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using Godot; /// @@ -40,7 +39,7 @@ public override void _EnterTree() { //创建玩家 - Player = new Player(); + Player = ActivityObject.Create(ActivityIdPrefix.Role + "0001"); Player.Position = new Vector2(30, 30); Player.Name = "Player"; Player.PutDown(RoomLayerEnum.YSortLayer); @@ -77,49 +76,49 @@ //播放bgm SoundManager.PlayMusic(ResourcePath.resource_sound_bgm_Intro_ogg, -17f); - Player.PickUpWeapon(WeaponManager.GetGun("1001")); - // Player.PickUpWeapon(WeaponManager.GetGun("1002")); - Player.PickUpWeapon(WeaponManager.GetGun("1004")); - Player.PickUpWeapon(WeaponManager.GetGun("1003")); + Player.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0001")); + // Player.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0002")); + Player.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0004")); + Player.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0003")); - var enemy1 = new Enemy(); - enemy1.PutDown(new Vector2(160, 160), RoomLayerEnum.YSortLayer); - enemy1.PickUpWeapon(WeaponManager.GetGun("1001")); + // var enemy1 = new Enemy(); + // enemy1.PutDown(new Vector2(160, 160), RoomLayerEnum.YSortLayer); + // enemy1.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0001")); // for (int i = 0; i < 10; i++) // { // var enemyTemp = new Enemy(); // enemyTemp.PutDown(new Vector2(30 + (i + 1) * 20, 30), RoomLayerEnum.YSortLayer); - // // enemyTemp.PickUpWeapon(WeaponManager.GetGun("1003")); - // // enemyTemp.PickUpWeapon(WeaponManager.GetGun("1001")); + // // enemyTemp.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0003")); + // // enemyTemp.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0001")); // } // var enemy2 = new Enemy(); // enemy2.Name = "Enemy2"; // enemy2.PutDown(new Vector2(120, 100)); - // enemy2.PickUpWeapon(WeaponManager.GetGun("1002")); - // //enemy2.PickUpWeapon(WeaponManager.GetGun("1004")); - // //enemy2.PickUpWeapon(WeaponManager.GetGun("1003")); + // enemy2.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0002")); + // //enemy2.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0004")); + // //enemy2.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0003")); // // var enemy3 = new Enemy(); // enemy3.Name = "Enemy3"; // enemy3.PutDown(new Vector2(100, 120)); - // enemy3.PickUpWeapon(WeaponManager.GetGun("1003")); - // enemy3.PickUpWeapon(WeaponManager.GetGun("1002")); + // enemy3.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0003")); + // enemy3.PickUpWeapon(ActivityObject.Create(ActivityIdPrefix.Weapon + "0002")); - // WeaponManager.GetGun("1004").PutDown(new Vector2(80, 100), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1001").PutDown(new Vector2(220, 120), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1001").PutDown(new Vector2(230, 120), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1001").PutDown(new Vector2(80, 80), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1002").PutDown(new Vector2(80, 120), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1003").PutDown(new Vector2(120, 80), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1003").PutDown(new Vector2(130, 80), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1003").PutDown(new Vector2(140, 80), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0004").PutDown(new Vector2(80, 100), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0001").PutDown(new Vector2(220, 120), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0001").PutDown(new Vector2(230, 120), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0001").PutDown(new Vector2(80, 80), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0002").PutDown(new Vector2(80, 120), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0003").PutDown(new Vector2(120, 80), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0003").PutDown(new Vector2(130, 80), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0003").PutDown(new Vector2(140, 80), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1003").PutDown(new Vector2(180, 80), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1003").PutDown(new Vector2(180, 180), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1002").PutDown(new Vector2(180, 120), RoomLayerEnum.NormalLayer); - // WeaponManager.GetGun("1002").PutDown(new Vector2(180, 130), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0003").PutDown(new Vector2(180, 80), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0003").PutDown(new Vector2(180, 180), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0002").PutDown(new Vector2(180, 120), RoomLayerEnum.NormalLayer); + // ActivityObject.Create(ActivityIdPrefix.Weapon + "0002").PutDown(new Vector2(180, 130), RoomLayerEnum.NormalLayer); } diff --git a/DungeonShooting_Godot/src/test/TestActivity.cs b/DungeonShooting_Godot/src/test/TestActivity.cs index d5fee2e..0a9eb8d 100644 --- a/DungeonShooting_Godot/src/test/TestActivity.cs +++ b/DungeonShooting_Godot/src/test/TestActivity.cs @@ -1,8 +1,9 @@ using Godot; +[RegisterActivity(ActivityIdPrefix.Test + "1", ResourcePath.prefab_test_TestActivity_tscn)] public partial class TestActivity : ActivityObject { - public TestActivity() : base(ResourcePath.prefab_test_TestActivity_tscn) + public override void _Ready() { var externalForce = MoveController.AddConstantForce("move"); externalForce.Velocity = new Vector2(0, 60);