From d5983f236108f4ddd3c2a85e8abdba8497b72eff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E7=84=B6?= <1042742166@qq.com> Date: Tue, 21 Sep 2021 16:43:01 +0800 Subject: [PATCH 1/6] refactor!: change Preparation to Class Library, Move ALL enum types from their Interface/GameObj files to a new file EnumType.cs, Add Constant.cs. --- logic/.editorconfig | 4 ++++ logic/Preparation/GameObj/GameObj.cs | 6 +----- logic/Preparation/Interface/IGameObj.cs | 13 ------------- logic/Preparation/Preparation.csproj | 4 +++- logic/Preparation/Utility/Constant.cs | 26 +++++++++++++++++++++++++ logic/Preparation/Utility/EnumType.cs | 24 +++++++++++++++++++++++ logic/Server/Server.csproj | 4 ++++ logic/logic.sln | 5 +++++ 8 files changed, 67 insertions(+), 19 deletions(-) create mode 100644 logic/.editorconfig create mode 100644 logic/Preparation/Utility/Constant.cs create mode 100644 logic/Preparation/Utility/EnumType.cs diff --git a/logic/.editorconfig b/logic/.editorconfig new file mode 100644 index 00000000..b4d72b1e --- /dev/null +++ b/logic/.editorconfig @@ -0,0 +1,4 @@ +[*.cs] + +# CS8632: 只能在 "#nullable" 注释上下文内的代码中使用可为 null 的引用类型的注释。 +dotnet_diagnostic.CS8632.severity = suggestion diff --git a/logic/Preparation/GameObj/GameObj.cs b/logic/Preparation/GameObj/GameObj.cs index dfcfbefb..58296a06 100644 --- a/logic/Preparation/GameObj/GameObj.cs +++ b/logic/Preparation/GameObj/GameObj.cs @@ -5,11 +5,7 @@ namespace Preparation.GameObj { public abstract class GameObj:IGameObj { - public enum GameObjType - { - Character = 0, - Obj = 1 - } + protected readonly object gameObjLock = new object(); protected readonly XYPosition birthPos; diff --git a/logic/Preparation/Interface/IGameObj.cs b/logic/Preparation/Interface/IGameObj.cs index 067431df..0993ea9b 100644 --- a/logic/Preparation/Interface/IGameObj.cs +++ b/logic/Preparation/Interface/IGameObj.cs @@ -2,19 +2,6 @@ namespace Preparation.Interface { - public enum PlaceType //位置标志,包括陆地,草丛,以及角色技能带来的隐身。 - { - Land = 0, - Grass1 = 1, - Grass2 = 2, - Grass3 = 3, - Invisible = 4 - } - public enum ShapeType - { - Circle = 0, //仍然,子弹和人物为圆形,格子为方形 - Square = 1 - } public interface IGameObj { public long ID { get; } diff --git a/logic/Preparation/Preparation.csproj b/logic/Preparation/Preparation.csproj index 20827042..a61dc195 100644 --- a/logic/Preparation/Preparation.csproj +++ b/logic/Preparation/Preparation.csproj @@ -1,8 +1,10 @@ - Exe + Library net5.0 + + diff --git a/logic/Preparation/Utility/Constant.cs b/logic/Preparation/Utility/Constant.cs new file mode 100644 index 00000000..a829119e --- /dev/null +++ b/logic/Preparation/Utility/Constant.cs @@ -0,0 +1,26 @@ +using Preparation.GameObj; +using Preparation.Interface; + +namespace Preparation.Utility +{ + public static class Constant + { + public const int numOfPosGridPerCell = 1000; //每格的【坐标单位】数 + public const int numOfStepPerSecond = 20; //每秒行走的步数 + + public static XYPosition GetCellCenterPos(int x, int y) //求格子的中心坐标 + { + XYPosition ret = new XYPosition(x * numOfPosGridPerCell + numOfPosGridPerCell / 2, + y * numOfPosGridPerCell + numOfPosGridPerCell / 2); + return ret; + } + public static int PosGridToCellX(XYPosition pos) //求坐标所在的格子的x坐标 + { + return pos.x / numOfPosGridPerCell; + } + public static int PosGridToCellY(XYPosition pos) //求坐标所在的格子的y坐标 + { + return pos.y / numOfPosGridPerCell; + } + } +} diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs new file mode 100644 index 00000000..d57d9225 --- /dev/null +++ b/logic/Preparation/Utility/EnumType.cs @@ -0,0 +1,24 @@ +using Preparation.GameObj; +using Preparation.Interface; + +namespace Preparation.Utility +{ + public enum GameObjType + { + Player = 0, + Object = 1 + } + public enum ShapeType + { + Circle = 0, //仍然,子弹和人物为圆形,格子为方形 + Square = 1 + } + public enum PlaceType //位置标志,包括陆地,草丛,以及角色技能带来的隐身。 + { + Land = 0, + Grass1 = 1, + Grass2 = 2, + Grass3 = 3, + Invisible = 4 + } +} diff --git a/logic/Server/Server.csproj b/logic/Server/Server.csproj index 50384d50..dd105091 100644 --- a/logic/Server/Server.csproj +++ b/logic/Server/Server.csproj @@ -9,4 +9,8 @@ + + + + diff --git a/logic/logic.sln b/logic/logic.sln index 46184770..cbfaaa5a 100644 --- a/logic/logic.sln +++ b/logic/logic.sln @@ -11,6 +11,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preparation", "Preparation\ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameEngine", "GameEngine\GameEngine.csproj", "{C1CEF591-E65C-4E16-A369-F5F9EA46F978}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{9B4C0E80-31B4-4EAF-9205-D40F48068EE6}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU From 452c7e61dd2a254972c9ba61569e16e1bf2ac8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E7=84=B6?= <1042742166@qq.com> Date: Tue, 21 Sep 2021 19:05:27 +0800 Subject: [PATCH 2/6] chore: change all TAB to 4 spaces. --- logic/Preparation/Utility/Constant.cs | 34 +++++++++++++-------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/logic/Preparation/Utility/Constant.cs b/logic/Preparation/Utility/Constant.cs index a829119e..3ebafc0c 100644 --- a/logic/Preparation/Utility/Constant.cs +++ b/logic/Preparation/Utility/Constant.cs @@ -5,22 +5,22 @@ namespace Preparation.Utility { public static class Constant { - public const int numOfPosGridPerCell = 1000; //每格的【坐标单位】数 - public const int numOfStepPerSecond = 20; //每秒行走的步数 + public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 + public const int numOfStepPerSecond = 20; // 每秒行走的步数 - public static XYPosition GetCellCenterPos(int x, int y) //求格子的中心坐标 - { - XYPosition ret = new XYPosition(x * numOfPosGridPerCell + numOfPosGridPerCell / 2, - y * numOfPosGridPerCell + numOfPosGridPerCell / 2); - return ret; - } - public static int PosGridToCellX(XYPosition pos) //求坐标所在的格子的x坐标 - { - return pos.x / numOfPosGridPerCell; - } - public static int PosGridToCellY(XYPosition pos) //求坐标所在的格子的y坐标 - { - return pos.y / numOfPosGridPerCell; - } - } + public static XYPosition GetCellCenterPos(int x, int y) // 求格子的中心坐标 + { + XYPosition ret = new XYPosition(x * numOfPosGridPerCell + numOfPosGridPerCell / 2, + y * numOfPosGridPerCell + numOfPosGridPerCell / 2); + return ret; + } + public static int PosGridToCellX(XYPosition pos) // 求坐标所在的格子的x坐标 + { + return pos.x / numOfPosGridPerCell; + } + public static int PosGridToCellY(XYPosition pos) // 求坐标所在的格子的y坐标 + { + return pos.y / numOfPosGridPerCell; + } + } } From 8b3be9a6d4ee0d7b643fb03ca75a823904d049b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E7=84=B6?= <1042742166@qq.com> Date: Tue, 21 Sep 2021 19:15:38 +0800 Subject: [PATCH 3/6] chore: change Constant.cs and move to Preparation folder. --- logic/Preparation/{Utility => }/Constant.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename logic/Preparation/{Utility => }/Constant.cs (96%) diff --git a/logic/Preparation/Utility/Constant.cs b/logic/Preparation/Constant.cs similarity index 96% rename from logic/Preparation/Utility/Constant.cs rename to logic/Preparation/Constant.cs index 3ebafc0c..785f6d79 100644 --- a/logic/Preparation/Utility/Constant.cs +++ b/logic/Preparation/Constant.cs @@ -1,5 +1,5 @@ using Preparation.GameObj; -using Preparation.Interface; +using Preparation.Utility; namespace Preparation.Utility { From 3320fab74e031f83e54bc4b0fcd05e46629bd3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E7=84=B6?= <1042742166@qq.com> Date: Fri, 24 Sep 2021 13:13:37 +0800 Subject: [PATCH 4/6] chore: add/change some gameobj(s) for teamwork. --- logic/Preparation/Constant.cs | 4 +- .../{GameObj => Deprecated}/MoveableObj.cs | 7 +- logic/Preparation/GameObj/BirthPoint.cs | 20 ++++++ logic/Preparation/GameObj/Character.cs | 27 +++++++ logic/Preparation/GameObj/GameObj.cs | 72 ++++++++++++++++++- logic/Preparation/GameObj/Grass.cs | 41 +++++++++++ logic/Preparation/GameObj/OutOfBoundBlock.cs | 20 ++++++ logic/Preparation/GameObj/Prop.cs | 35 +++++++++ logic/Preparation/GameObj/Wall.cs | 19 +++++ logic/Preparation/Interface/IGameObj.cs | 7 +- logic/Preparation/Interface/IMoveable.cs | 11 +-- logic/Preparation/Preparation.csproj | 2 +- logic/Preparation/Utility/EnumType.cs | 60 +++++++++++++++- 13 files changed, 310 insertions(+), 15 deletions(-) rename logic/Preparation/{GameObj => Deprecated}/MoveableObj.cs (92%) create mode 100644 logic/Preparation/GameObj/BirthPoint.cs create mode 100644 logic/Preparation/GameObj/Character.cs create mode 100644 logic/Preparation/GameObj/Grass.cs create mode 100644 logic/Preparation/GameObj/OutOfBoundBlock.cs create mode 100644 logic/Preparation/GameObj/Prop.cs create mode 100644 logic/Preparation/GameObj/Wall.cs diff --git a/logic/Preparation/Constant.cs b/logic/Preparation/Constant.cs index 785f6d79..98282716 100644 --- a/logic/Preparation/Constant.cs +++ b/logic/Preparation/Constant.cs @@ -1,7 +1,7 @@ using Preparation.GameObj; using Preparation.Utility; -namespace Preparation.Utility +namespace Preparation { public static class Constant { @@ -23,4 +23,4 @@ public static int PosGridToCellY(XYPosition pos) // 求坐标所在的格 return pos.y / numOfPosGridPerCell; } } -} +} \ No newline at end of file diff --git a/logic/Preparation/GameObj/MoveableObj.cs b/logic/Preparation/Deprecated/MoveableObj.cs similarity index 92% rename from logic/Preparation/GameObj/MoveableObj.cs rename to logic/Preparation/Deprecated/MoveableObj.cs index cc03079b..d00c9b08 100644 --- a/logic/Preparation/GameObj/MoveableObj.cs +++ b/logic/Preparation/Deprecated/MoveableObj.cs @@ -1,4 +1,8 @@ -using Preparation.Interface; + +//已弃用:MoveableObj类,包含属性在抽象/具体类实现 + +/* +using Preparation.Interface; using Preparation.Utility; namespace Preparation.GameObj @@ -50,3 +54,4 @@ public virtual void Reset() //复活时数据重置 } } } +//*/ \ No newline at end of file diff --git a/logic/Preparation/GameObj/BirthPoint.cs b/logic/Preparation/GameObj/BirthPoint.cs new file mode 100644 index 00000000..424bdfa3 --- /dev/null +++ b/logic/Preparation/GameObj/BirthPoint.cs @@ -0,0 +1,20 @@ +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + /// + /// 出生点 + /// + public class BirthPoint : GameObj + { + public BirthPoint(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) + { + this.CanMove = false; + this.Type = GameObjType.BirthPoint; + } + public override bool IsRigid => false; // 与THUAI4不同,改成了非刚体 + protected override bool IgnoreCollideExecutor(IGameObj targetObj) => true; // 出生点不与任何东西碰撞 + public override ShapeType Shape => ShapeType.Square; // 与THUAI4不同,改成了方形 + } +} diff --git a/logic/Preparation/GameObj/Character.cs b/logic/Preparation/GameObj/Character.cs new file mode 100644 index 00000000..160fdddb --- /dev/null +++ b/logic/Preparation/GameObj/Character.cs @@ -0,0 +1,27 @@ +using System; +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + public abstract partial class Character : GameObj, ICharacter //负责人LHR摆烂中... + { + public const int basicAp = 1000; + public const int basicHp = 6000; + public const int basicCD = 1000; + + private long teamID = long.MaxValue; + public long TeamID + { + get => teamID; + set + { + lock (gameObjLock) + { + teamID = value; + //Debugger.Output(this, " joins in the tream: " + value.ToString()); + } + } + } + } +} diff --git a/logic/Preparation/GameObj/GameObj.cs b/logic/Preparation/GameObj/GameObj.cs index 58296a06..cd077cc6 100644 --- a/logic/Preparation/GameObj/GameObj.cs +++ b/logic/Preparation/GameObj/GameObj.cs @@ -3,12 +3,33 @@ namespace Preparation.GameObj { - public abstract class GameObj:IGameObj + /// + /// 一切游戏元素的总基类,与THUAI4不同,继承IMoveable接口(出于一切物体其实都是可运动的指导思想)——LHR + /// + public abstract class GameObj : IMoveable { protected readonly object gameObjLock = new object(); + /// + /// 可移动物体专用锁 + /// + public object MoveLock => gameObjLock; + protected readonly XYPosition birthPos; + private GameObjType type; + public GameObjType Type + { + get => type; + set + { + lock (gameObjLock) + { + type = value; + } + } + } + public long ID { get;} private XYPosition position; @@ -91,6 +112,21 @@ public PlaceType Place } } + protected int moveSpeed; + /// + /// 移动速度 + /// + public int MoveSpeed + { + get => moveSpeed; + protected set + { + lock (gameObjLock) + { + moveSpeed = value; + } + } + } public virtual bool CanSee(GameObj obj) { if (obj.Place == PlaceType.Invisible) //先判断是否隐身 @@ -101,7 +137,39 @@ public virtual bool CanSee(GameObj obj) return true; return false; } - + // 移动,改变坐标 + public long Move(Vector moveVec) + { + var XYVec = Vector.Vector2XY(moveVec); + lock (gameObjLock) + { + FacingDirection = moveVec.angle; + this.Position += XYVec; + } + return (long)(XYVec.ToVector2() * new Vector2(0, 0)); + } + /// + /// 复活时数据重置 + /// + public virtual void Reset() + { + lock (gameObjLock) + { + + FacingDirection = 0.0; + IsMoving = false; + CanMove = false; + IsResetting = true; + this.Position = birthPos; + } + } + /// + /// 为了使IgnoreCollide多态化并使GameObj能不报错地继承IMoveable + /// 在xfgg点播下设计了这个抽象辅助方法,在具体类中实现 + /// + /// 依具体类及该方法参数而定,默认为false + protected virtual bool IgnoreCollideExecutor(IGameObj targetObj)=>false; + bool IMoveable.IgnoreCollide(IGameObj targetObj) => IgnoreCollideExecutor(targetObj); public GameObj(XYPosition initPos,int initRadius,PlaceType initPlace) { this.birthPos = initPos; diff --git a/logic/Preparation/GameObj/Grass.cs b/logic/Preparation/GameObj/Grass.cs new file mode 100644 index 00000000..c69248ab --- /dev/null +++ b/logic/Preparation/GameObj/Grass.cs @@ -0,0 +1,41 @@ +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + /// + /// 草丛 + /// + public abstract class Grass : GameObj + { + public Grass(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) + { + this.CanMove = false; + this.Type = GameObjType.Grass; + } + public override bool IsRigid => false; + protected override bool IgnoreCollideExecutor(IGameObj targetObj) => true; //草丛不与任何东西碰撞 + public override ShapeType Shape => ShapeType.Square; + } + public class Grass1:Grass + { + public Grass1(XYPosition initPos, int radius) : base(initPos, radius) + { + this.Place = PlaceType.Grass1; + } + } + public class Grass2 : Grass + { + public Grass2(XYPosition initPos, int radius) : base(initPos, radius) + { + this.Place = PlaceType.Grass2; + } + } + public class Grass3 : Grass + { + public Grass3(XYPosition initPos, int radius) : base(initPos, radius) + { + this.Place = PlaceType.Grass1; + } + } +} diff --git a/logic/Preparation/GameObj/OutOfBoundBlock.cs b/logic/Preparation/GameObj/OutOfBoundBlock.cs new file mode 100644 index 00000000..2e01ef77 --- /dev/null +++ b/logic/Preparation/GameObj/OutOfBoundBlock.cs @@ -0,0 +1,20 @@ +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + /// + /// 逻辑墙 + /// + public class OutOfBoundBlock:GameObj + { + public OutOfBoundBlock(XYPosition initPos) : base(initPos, int.MaxValue, PlaceType.Land) + { + this.CanMove = false; + this.Type = GameObjType.OutOfBoundBlock; + } + + public override bool IsRigid => true; + public override ShapeType Shape => ShapeType.Square; + } +} diff --git a/logic/Preparation/GameObj/Prop.cs b/logic/Preparation/GameObj/Prop.cs new file mode 100644 index 00000000..238a8d0e --- /dev/null +++ b/logic/Preparation/GameObj/Prop.cs @@ -0,0 +1,35 @@ +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + public abstract class Prop : GameObj // 负责人LHR摆烂中... + { + public const int MinPropTypeNum = 1; + public const int MaxPropTypeNum = 10; + + protected bool laid = false; //道具是否已放置 + public bool Laid => laid; + + public override bool IsRigid => true; + + protected override bool IgnoreCollideExecutor(IGameObj targetObj) => true; //道具不与任何东西碰撞 + + public abstract PropType GetPropType(); + + public void ResetPosition(XYPosition pos) + { + Position = pos; + } + public void ResetMoveSpeed(int newMoveSpeed) + { + MoveSpeed = newMoveSpeed; + } + + public Prop(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) + { + this.CanMove = false; + this.Type = GameObjType.Prop; + } + } +} diff --git a/logic/Preparation/GameObj/Wall.cs b/logic/Preparation/GameObj/Wall.cs new file mode 100644 index 00000000..ebd7ec9d --- /dev/null +++ b/logic/Preparation/GameObj/Wall.cs @@ -0,0 +1,19 @@ +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + /// + /// 墙体 + /// + public class Wall : GameObj + { + public Wall(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) + { + this.CanMove = false; + this.Type = GameObjType.Wall; + } + public override bool IsRigid => true; + public override ShapeType Shape => ShapeType.Square; + } +} diff --git a/logic/Preparation/Interface/IGameObj.cs b/logic/Preparation/Interface/IGameObj.cs index 0993ea9b..b6d04250 100644 --- a/logic/Preparation/Interface/IGameObj.cs +++ b/logic/Preparation/Interface/IGameObj.cs @@ -4,16 +4,17 @@ namespace Preparation.Interface { public interface IGameObj { + public GameObjType Type { get; set; } //将THUAI4的getgameobjtype方法改为此接口属性 public long ID { get; } - public XYPosition Position { get; } //if Square, Pos equals the center + public XYPosition Position { get; } // if Square, Pos equals the center public double FacingDirection { get; } public bool IsRigid { get; } public ShapeType Shape { get; } public bool CanMove { get; set; } public bool IsMoving { get; set; } - public bool IsResetting { get; set; } //reviving + public bool IsResetting { get; set; } // reviving public bool IsAvailable { get; } - public int Radius { get; } //if Square, Radius equals half length of one side + public int Radius { get; } // if Square, Radius equals half length of one side public PlaceType Place { get; set; } } diff --git a/logic/Preparation/Interface/IMoveable.cs b/logic/Preparation/Interface/IMoveable.cs index 90ac4382..a4ea6314 100644 --- a/logic/Preparation/Interface/IMoveable.cs +++ b/logic/Preparation/Interface/IMoveable.cs @@ -5,14 +5,17 @@ namespace Preparation.Interface { public interface IMoveable:IGameObj { + object MoveLock { get; } public int MoveSpeed { get; } public long Move(Vector moveVec); - - public bool WillCollideWith(IGameObj targetObj,XYPosition nextPos) //检查下一位置是否会和目标物碰撞 - { //会移动的只有子弹和人物,都是Circle + protected bool IgnoreCollide(IGameObj targetObj); // 忽略碰撞,在具体类中实现 + public bool WillCollideWith(IGameObj targetObj,XYPosition nextPos) // 检查下一位置是否会和目标物碰撞 + { // 会移动的只有子弹和人物,都是Circle if (!targetObj.IsRigid || targetObj.ID == ID) return false; - if(targetObj.Shape==ShapeType.Circle) + if (IgnoreCollide(targetObj)) + return false; + if (targetObj.Shape==ShapeType.Circle) { return XYPosition.Distance(nextPos, targetObj.Position) < targetObj.Radius + Radius; } diff --git a/logic/Preparation/Preparation.csproj b/logic/Preparation/Preparation.csproj index a61dc195..dcf2855b 100644 --- a/logic/Preparation/Preparation.csproj +++ b/logic/Preparation/Preparation.csproj @@ -1,4 +1,4 @@ - + Library diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index d57d9225..8acd50cb 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -3,10 +3,18 @@ namespace Preparation.Utility { + /// + /// 存放所有用到的枚举类型 + /// public enum GameObjType { - Player = 0, - Object = 1 + Character = 0, + Wall = 1, + Prop = 2, + Bullet = 3, + BirthPoint = 4, + OutOfBoundBlock = 5, + Grass = 6 } public enum ShapeType { @@ -21,4 +29,52 @@ public enum PlaceType //位置标志,包括陆地,草丛,以及角色技 Grass3 = 3, Invisible = 4 } + enum BulletType //子弹的类型 + { + Bullet0 = 0, //普通子弹 + Bullet1 = 1 //爆弾 + } + public enum PropType // 道具的类型 + { + Null = 0, + Accelerate = 1, + plusAP = 2, + minusCD = 3, + addHP = 4, + Shield = 5, + addLIFE = 6, + Spear = 7, + Decelerate = 8, + minusAP = 9, + addCD = 10 + } + enum PassiveSkillType // 被动技能 + { + PSkill0 = 0, + PSkill1 = 1, + PSkill2 = 2, + PSkill3 = 3, + PSkill4 = 4, + PSkill5 = 5 + } + enum ActiveSkillType // 主动技能 + { + ASkill0 = 0, + ASkill1 = 1, + ASkill2 = 2, + ASkill3 = 3, + ASkill4 = 4, + ASkill5 = 5 + } + /*public enum JobType : int // 职业,貌似被废弃了。——LHR + { + Job0 = 0, + Job1 = 1, + Job2 = 2, + Job3 = 3, + Job4 = 4, + Job5 = 5, + Job6 = 6, + InvalidJobType = int.MaxValue + }*/ } From a73c1aace78abddc620ac4b4c8287cbbb89b2c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E7=84=B6?= <1042742166@qq.com> Date: Fri, 24 Sep 2021 13:25:10 +0800 Subject: [PATCH 5/6] chore: make all enum public. --- logic/Preparation/Utility/EnumType.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 8acd50cb..443417b4 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -29,7 +29,7 @@ public enum PlaceType //位置标志,包括陆地,草丛,以及角色技 Grass3 = 3, Invisible = 4 } - enum BulletType //子弹的类型 + public enum BulletType //子弹的类型 { Bullet0 = 0, //普通子弹 Bullet1 = 1 //爆弾 @@ -48,7 +48,7 @@ public enum PropType // 道具的类型 minusAP = 9, addCD = 10 } - enum PassiveSkillType // 被动技能 + public enum PassiveSkillType // 被动技能 { PSkill0 = 0, PSkill1 = 1, @@ -57,7 +57,7 @@ enum PassiveSkillType // 被动技能 PSkill4 = 4, PSkill5 = 5 } - enum ActiveSkillType // 主动技能 + public enum ActiveSkillType // 主动技能 { ASkill0 = 0, ASkill1 = 1, From f59742773b556de1ffe7255af2f8d7c2f817bc5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E6=B5=A9=E7=84=B6?= <1042742166@qq.com> Date: Sat, 25 Sep 2021 18:08:16 +0800 Subject: [PATCH 6/6] chore: Add Character(partial, abstract) and Prop(abstract). --- logic/Preparation/Constant.cs | 17 + logic/Preparation/GameObj/BirthPoint.cs | 16 +- logic/Preparation/GameObj/Character.cs | 373 +++++++++++++++++++- logic/Preparation/GameObj/GameObj.cs | 23 +- logic/Preparation/GameObj/ObjOfCharacter.cs | 26 ++ logic/Preparation/GameObj/Prop.cs | 34 +- logic/Preparation/Interface/ICharacter.cs | 2 + logic/Preparation/Preparation.csproj | 2 +- logic/Preparation/Utility/EnumType.cs | 9 + 9 files changed, 455 insertions(+), 47 deletions(-) create mode 100644 logic/Preparation/GameObj/ObjOfCharacter.cs diff --git a/logic/Preparation/Constant.cs b/logic/Preparation/Constant.cs index 98282716..cb3e9bb4 100644 --- a/logic/Preparation/Constant.cs +++ b/logic/Preparation/Constant.cs @@ -5,6 +5,9 @@ namespace Preparation { public static class Constant { + /// + /// 基础常数与常方法 + /// public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 public const int numOfStepPerSecond = 20; // 每秒行走的步数 @@ -22,5 +25,19 @@ public static int PosGridToCellY(XYPosition pos) // 求坐标所在的格 { return pos.y / numOfPosGridPerCell; } + /// + /// 玩家相关 + /// + public const int basicAp = 1000; // 初始攻击力 + public const int basicHp = 6000; // 初始血量 + public const int basicCD = 1000; // 初始冷却 + public const int basicBulletNum = 12; // 初始子弹量(如果是射手) + public const int MinAP = 0; // 最小攻击力 + public const int MaxAP = int.MaxValue; //最大攻击力 + /// + /// 道具相关 + /// + public const int MinPropTypeNum = 1; + public const int MaxPropTypeNum = 10; } } \ No newline at end of file diff --git a/logic/Preparation/GameObj/BirthPoint.cs b/logic/Preparation/GameObj/BirthPoint.cs index 424bdfa3..ad54529a 100644 --- a/logic/Preparation/GameObj/BirthPoint.cs +++ b/logic/Preparation/GameObj/BirthPoint.cs @@ -6,15 +6,23 @@ namespace Preparation.GameObj /// /// 出生点 /// - public class BirthPoint : GameObj + public class BirthPoint : ObjOfCharacter { public BirthPoint(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) { this.CanMove = false; this.Type = GameObjType.BirthPoint; } - public override bool IsRigid => false; // 与THUAI4不同,改成了非刚体 - protected override bool IgnoreCollideExecutor(IGameObj targetObj) => true; // 出生点不与任何东西碰撞 + // 修改建议:需要避免非自己的玩家进入出生点,否则会重叠 + public override bool IsRigid => true; + protected override bool IgnoreCollideExecutor(IGameObj targetObj) + { + if (targetObj.Type != GameObjType.Character) + return true; // 非玩家不碰撞 + else if (targetObj.Type == GameObjType.Character && targetObj.ID == this.Parent.ID) + return true; // 出生点所属的玩家不碰撞 + return false; + } public override ShapeType Shape => ShapeType.Square; // 与THUAI4不同,改成了方形 } -} +} \ No newline at end of file diff --git a/logic/Preparation/GameObj/Character.cs b/logic/Preparation/GameObj/Character.cs index 160fdddb..c5e95347 100644 --- a/logic/Preparation/GameObj/Character.cs +++ b/logic/Preparation/GameObj/Character.cs @@ -4,24 +4,359 @@ namespace Preparation.GameObj { - public abstract partial class Character : GameObj, ICharacter //负责人LHR摆烂中... + public abstract partial class Character : GameObj, ICharacter // 负责人LHR摆烂中...该文件下抽象部分类已基本完工,剩下的在buffmanager里写 { - public const int basicAp = 1000; - public const int basicHp = 6000; - public const int basicCD = 1000; - - private long teamID = long.MaxValue; - public long TeamID - { - get => teamID; - set - { - lock (gameObjLock) - { - teamID = value; - //Debugger.Output(this, " joins in the tream: " + value.ToString()); - } - } - } - } + public readonly object propLock = new object(); + private object beAttackedLock = new object(); + public object PropLock => propLock; + + #region 角色的基本属性及方法,包括与道具、子弹的交互方法 + /// + /// 装弹冷却/近战攻击冷却 + /// + protected int cd; + public int CD + { + get => cd; + private set + { + lock (gameObjLock) + { + cd = value; + //Debugger.Output(this, string.Format("'s CD has been set to: {0}.", value)); + } + } + } + public int OrgCD { get; protected set; } // 原初冷却 + protected int maxBulletNum; + public int MaxBulletNum => maxBulletNum; // 人物最大子弹数 + protected int bulletNum; + public int BulletNum => bulletNum; // 目前持有的子弹数 + public int MaxHp { get; protected set; } // 最大血量 + protected int hp; + public int HP => hp; // 当前血量 + private int deathCount = 0; + public int DeathCount => deathCount; // 玩家的死亡次数 + protected int ap; // 当前攻击力 + public int AP + { + get => ap; + private set + { + lock (gameObjLock) + { + ap = value; + //Debugger.Output(this, "'s AP has been set to: " + value.ToString()); + } + } + } + public int OrgAp { get; protected set; } // 原初攻击力 + private int score; + public int Score => score; // 当前分数 + + private Prop? propInventory; + public Prop? PropInventory //持有的道具 + { + get => propInventory; + set + { + lock (gameObjLock) + { + propInventory = value; + //Debugger.Output(this, " picked the prop: " + (holdProp == null ? "null" : holdProp.ToString())); + } + } + } + /// + /// 使用物品栏中的道具 + /// + /// 被使用的道具 + public Prop? UseProp() + { + lock (gameObjLock) + { + var oldProp = PropInventory; + PropInventory = null; + return oldProp; + } + } + /// + /// 是否正在更换道具(包括捡起与抛出) + /// + private bool isModifyingProp = false; + public bool IsModifyingProp + { + get => isModifyingProp; + set + { + lock (gameObjLock) + { + isModifyingProp = value; + } + } + } + + public abstract BulletType Bullet { get; } //人物的发射子弹类型,射程伤害等信息存在具体子弹里 + /// + /// 进行一次远程攻击 + /// + /// + /// + /// + /// 攻击操作发出的子弹 + public Bullet? RemoteAttack(XYPosition posOffset, int bulletRadius, int basicBulletMoveSpeed) + { + if (TrySubBulletNum()) return ProduceOneBullet(posOffset, bulletRadius, basicBulletMoveSpeed); + else return null; + } + /// + /// 产生一颗子弹 + /// + /// + /// + /// + /// 产生的子弹 + protected abstract Bullet ProduceOneBullet(XYPosition posOffset, int bulletRadius, int basicBulletMoveSpeed); + + /// + /// 尝试将子弹数量减1 + /// + /// 减操作是否成功 + private bool TrySubBulletNum() + { + lock (gameObjLock) + { + if (bulletNum > 0) + { + --bulletNum; + return true; + } + return false; + } + } + /// + /// 尝试将子弹数量加1 + /// + /// 加操作是否成功 + public bool TryAddBulletNum() + { + lock (gameObjLock) + { + if (bulletNum < maxBulletNum) + { + ++bulletNum; + return true; + } + return false; + } + } + /// + /// 尝试加血 + /// + /// 欲加量 + /// 加操作是否成功 + public bool TryAddHp(int add) + { + lock (gameObjLock) + { + if(hp < MaxHp) + { + hp = MaxHp > hp + add ? hp + add : MaxHp; + //Debugger.Output(this, " hp has added to: " + hp.ToString()); + return true; + } + return false; + } + } + /// + /// 尝试减血 + /// + /// 减血量 + /// 减操作是否成功 + public bool TrySubHp(int sub) + { + lock (gameObjLock) + { + if (hp > 0) + { + hp = 0 >= hp - sub ? 0 : hp - sub; + //Debugger.Output(this, " hp has subed to: " + hp.ToString()); + return true; + } + return false; + } + } + /// + /// 增加死亡次数 + /// + /// 当前死亡次数 + private int AddDeathCount() + { + lock (gameObjLock) + { + ++deathCount; + return deathCount; + } + } + /// + /// 加分 + /// + /// 增加量 + public void AddScore(int add) + { + lock (gameObjLock) + { + score += add; + //Debugger.Output(this, " 's score has been added to: " + score.ToString()); + } + } + /// + /// 减分 + /// + /// 减少量 + public void SubScore(int sub) + { + lock (gameObjLock) + { + score -= sub; + //Debugger.Output(this, " 's score has been subed to: " + score.ToString()); + } + } + /// + /// 遭受攻击 + /// + /// + /// + /// 伤害来源 + /// 是否因该攻击而死 + public bool BeAttack(int subHP, bool hasSpear, Character? attacker) + { + lock (beAttackedLock) + { + if (hp <= 0) return false; + if (!(attacker?.TeamID == this.TeamID)) + { + if (hasSpear || !HasShield) TrySubHp(subHP); + if (hp <= 0) TryActivatingTotem(); + if (Job == JobType.Job6) attacker?.BeBounced(subHP * 3 / 4, this.HasSpear, this); //职业6可以反弹伤害 + } + else if (attacker?.Job == JobType.Job6) + { + TryAddHp(subHP * 6); // 职业六回血6倍 + } + return hp <= 0; + } + } + /// + /// 攻击被反弹,反弹伤害不会再被反弹 + /// + /// + /// + /// 反弹伤害者 + /// 是否因反弹伤害而死 + private bool BeBounced(int subHP, bool hasSpear, Character? bouncer) + { + lock (beAttackedLock) + { + if (hp <= 0) return false; + if (!(bouncer?.TeamID == this.TeamID)) + { + if (hasSpear || !HasShield) TrySubHp(subHP); + if (hp <= 0) TryActivatingTotem(); + } + else if (attacker?.Job == JobType.Job6) + { + TryAddHp(subHP * 6); // 职业六回血6倍 + } + return hp <= 0; + } + } + /// + /// 角色所属队伍ID + /// + private long teamID = long.MaxValue; + public long TeamID + { + get => teamID; + set + { + lock (gameObjLock) + { + teamID = value; + //Debugger.Output(this, " joins in the team: " + value.ToString()); + } + } + } + /// + /// 角色携带的信息 + /// + private string message = "THUAI5"; + public string Message + { + get => message; + set + { + lock (gameObjLock) + { + message = value; + } + } + } + #endregion + + #region 角色拥有的buff相关属性、方法(目前还是完全照搬的) + public void AddMoveSpeed(double add, int buffTime) => buffManeger.AddMoveSpeed(add, buffTime, newVal => { MoveSpeed = newVal; }, OrgMoveSpeed); + + public void AddAP(double add, int buffTime) => buffManeger.AddAP(add, buffTime, newVal => { AP = newVal; }, OrgAp); + + public void ChangeCD(double discount, int buffTime) => buffManeger.ChangeCD(discount, buffTime, newVal => { CD = newVal; }, OrgCD); + + public void AddShield(int shieldTime) => buffManeger.AddShield(shieldTime); + public bool HasShield => buffManeger.HasShield; + + public void AddLIFE(int LIFETime) => buffManeger.AddLIFE(LIFETime); + public bool HasTotem => buffManeger.HasTotem; + + public void AddSpear(int spearTime) => buffManeger.AddSpear(spearTime); + public bool HasSpear => buffManeger.HasSpear; + + private void TryActivatingTotem() + { + if (buffManeger.TryActivatingTotem()) + { + hp = MaxHp; + } + } + #endregion + public override void Reset() + { + AddDeathCount(); + base.Reset(); + this.moveSpeed = OrgMoveSpeed; + hp = MaxHp; + ap = OrgAp; + PropInventory = null; + bulletNum = maxBulletNum / 2; + buffManeger.ClearAll(); + } + public override bool IsRigid => true; + protected override bool IgnoreCollideExecutor(IGameObj targetObj) + { + if (targetObj is BirthPoint && object.ReferenceEquals(((BirthPoint)targetObj).Parent, this)) // 自己的出生点可以忽略碰撞 + { + return true; + } + else if (targetObj is Mine && ((Mine)targetObj).Parent?.TeamID == TeamID) // 自己队的炸弹忽略碰撞 + { + return true; + } + return false; + } + public Character(XYPosition initPos, int initRadius, PlaceType initPlace, int initSpeed) :base(initPos,initRadius,initPlace) + { + this.CanMove = true; + this.Type = GameObjType.Character; + this.moveSpeed = initSpeed; + } + } } diff --git a/logic/Preparation/GameObj/GameObj.cs b/logic/Preparation/GameObj/GameObj.cs index cd077cc6..11d59609 100644 --- a/logic/Preparation/GameObj/GameObj.cs +++ b/logic/Preparation/GameObj/GameObj.cs @@ -127,6 +127,11 @@ protected set } } } + /// + /// 原初移动速度,THUAI4在Character类中 + /// + private int orgMoveSpeed; + public int OrgMoveSpeed { get => orgMoveSpeed; protected set { orgMoveSpeed = value; } } public virtual bool CanSee(GameObj obj) { if (obj.Place == PlaceType.Invisible) //先判断是否隐身 @@ -149,6 +154,22 @@ public long Move(Vector moveVec) return (long)(XYVec.ToVector2() * new Vector2(0, 0)); } /// + /// 设置位置 + /// + /// 新位置 + public void SetPosition(XYPosition newpos) + { + Position = newpos; + } + /// + /// 设置移动速度 + /// + /// 新速度 + public void SetMoveSpeed(int newMoveSpeed) + { + MoveSpeed = newMoveSpeed; + } + /// /// 复活时数据重置 /// public virtual void Reset() @@ -168,7 +189,7 @@ public virtual void Reset() /// 在xfgg点播下设计了这个抽象辅助方法,在具体类中实现 /// /// 依具体类及该方法参数而定,默认为false - protected virtual bool IgnoreCollideExecutor(IGameObj targetObj)=>false; + protected virtual bool IgnoreCollideExecutor(IGameObj targetObj) => false; bool IMoveable.IgnoreCollide(IGameObj targetObj) => IgnoreCollideExecutor(targetObj); public GameObj(XYPosition initPos,int initRadius,PlaceType initPlace) { diff --git a/logic/Preparation/GameObj/ObjOfCharacter.cs b/logic/Preparation/GameObj/ObjOfCharacter.cs new file mode 100644 index 00000000..71f75c09 --- /dev/null +++ b/logic/Preparation/GameObj/ObjOfCharacter.cs @@ -0,0 +1,26 @@ +using Preparation.Interface; +using Preparation.Utility; + +namespace Preparation.GameObj +{ + /// + /// 所有物,玩家可以存进“物品栏”的东西 + /// + public abstract class ObjOfCharacter : GameObj, IObjOfCharacter + { + private ICharacter? parent = null; //道具的主人 + public ICharacter? Parent + { + get => parent; + set + { + lock (gameObjLock) + { + parent = value; + } + } + } + // LHR注:本来考虑在构造函数里设置parent属性,见THUAI4在游戏引擎中才设置该属性,作罢。——2021/9/24 + public ObjOfCharacter(XYPosition initPos, int initRadius, PlaceType initPlace):base(initPos,initRadius,initPlace){} + } +} diff --git a/logic/Preparation/GameObj/Prop.cs b/logic/Preparation/GameObj/Prop.cs index 238a8d0e..f2c9fb7f 100644 --- a/logic/Preparation/GameObj/Prop.cs +++ b/logic/Preparation/GameObj/Prop.cs @@ -3,33 +3,23 @@ namespace Preparation.GameObj { - public abstract class Prop : GameObj // 负责人LHR摆烂中... + public abstract class Prop : ObjOfCharacter //LHR摆烂中...抽象类已写完 { - public const int MinPropTypeNum = 1; - public const int MaxPropTypeNum = 10; + protected bool laid = false; + public bool Laid => laid; // 道具是否放置在地图上 - protected bool laid = false; //道具是否已放置 - public bool Laid => laid; + public override bool IsRigid => true; - public override bool IsRigid => true; + protected override bool IgnoreCollideExecutor(IGameObj targetObj) => true; //道具不与任何东西碰撞 - protected override bool IgnoreCollideExecutor(IGameObj targetObj) => true; //道具不与任何东西碰撞 + public override ShapeType Shape => ShapeType.Square; public abstract PropType GetPropType(); - public void ResetPosition(XYPosition pos) - { - Position = pos; - } - public void ResetMoveSpeed(int newMoveSpeed) - { - MoveSpeed = newMoveSpeed; - } - - public Prop(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) - { - this.CanMove = false; - this.Type = GameObjType.Prop; - } - } + public Prop(XYPosition initPos, int radius) : base(initPos, radius, PlaceType.Land) + { + this.CanMove = false; + this.Type = GameObjType.Prop; + } + } } diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index afe36a8c..0b5f2b8b 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -1,9 +1,11 @@ using System; +using Preparation.Utility; namespace Preparation.Interface { public interface ICharacter:IGameObj { + object PropLock { get; } public long TeamID { get; } } } diff --git a/logic/Preparation/Preparation.csproj b/logic/Preparation/Preparation.csproj index dcf2855b..a61dc195 100644 --- a/logic/Preparation/Preparation.csproj +++ b/logic/Preparation/Preparation.csproj @@ -1,4 +1,4 @@ - + Library diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 443417b4..94508d13 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -66,6 +66,15 @@ public enum ActiveSkillType // 主动技能 ASkill4 = 4, ASkill5 = 5 } + public enum BuffType //buff + { + MoveSpeed = 0, + AP = 1, + CD = 2, + Shield = 3, + AddLIFE = 4, + Spear = 5 + } /*public enum JobType : int // 职业,貌似被废弃了。——LHR { Job0 = 0,