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);