diff --git a/logic/GameClass/GameClass.csproj b/logic/GameClass/GameClass.csproj new file mode 100644 index 00000000..7311ad08 --- /dev/null +++ b/logic/GameClass/GameClass.csproj @@ -0,0 +1,14 @@ + + + + net5.0 + + + + + + + + + + diff --git a/logic/Preparation/GameObj/BirthPoint.cs b/logic/GameClass/GameObj/BirthPoint.cs similarity index 87% rename from logic/Preparation/GameObj/BirthPoint.cs rename to logic/GameClass/GameObj/BirthPoint.cs index ef01c19e..298c4d75 100644 --- a/logic/Preparation/GameObj/BirthPoint.cs +++ b/logic/GameClass/GameObj/BirthPoint.cs @@ -2,14 +2,14 @@ using Preparation.Utility; using Preparation.GameData; -namespace Preparation.GameObj +namespace GameClass.GameObj { /// /// 出生点 /// public class BirthPoint : ObjOfCharacter { - public BirthPoint(XYPosition initPos) : base(initPos, Constant.numOfPosGridPerCell, PlaceType.Land) + public BirthPoint(XYPosition initPos) : base(initPos, GameData.numOfPosGridPerCell, PlaceType.Land) { this.CanMove = false; this.Type = GameObjType.BirthPoint; diff --git a/logic/Preparation/GameObj/Bullet.cs b/logic/GameClass/GameObj/Bullet.cs similarity index 96% rename from logic/Preparation/GameObj/Bullet.cs rename to logic/GameClass/GameObj/Bullet.cs index 5609ecff..2c6cbd17 100644 --- a/logic/Preparation/GameObj/Bullet.cs +++ b/logic/GameClass/GameObj/Bullet.cs @@ -2,7 +2,7 @@ using Preparation.Interface; using Preparation.Utility; -namespace Preparation.GameObj +namespace GameClass.GameObj { public abstract class Bullet : ObjOfCharacter // LHR摸鱼中...已写完抽象类及一个派生类 { @@ -75,7 +75,7 @@ public Bullet0(XYPosition initPos, int radius, int initSpeed, int ap, bool hasSp public Bullet0(Character player, int radius, int initSpeed, int ap) : base(player, radius, initSpeed, ap) { } public override bool IsRigid => true; public override ShapeType Shape => ShapeType.Circle; - public override double BulletBombRange => Constant.basicBulletBombRange; + public override double BulletBombRange => GameData.basicBulletBombRange; public override bool CanAttack(GameObj target) { @@ -89,7 +89,7 @@ public AtomBomb(XYPosition initPos, int radius, int initSpeed, int ap, bool hasS public AtomBomb(Character player, int radius, int initSpeed, int ap) : base(player, radius, initSpeed, ap) { } public override bool IsRigid => true; public override ShapeType Shape => ShapeType.Circle; - public override double BulletBombRange => 3 * Constant.basicBulletBombRange; + public override double BulletBombRange => 3 * GameData.basicBulletBombRange; public override bool CanAttack(GameObj target) { diff --git a/logic/Preparation/GameObj/Character.BuffManager.cs b/logic/GameClass/GameObj/Character.BuffManager.cs similarity index 96% rename from logic/Preparation/GameObj/Character.BuffManager.cs rename to logic/GameClass/GameObj/Character.BuffManager.cs index cf9a9cde..b6b63dfa 100644 --- a/logic/Preparation/GameObj/Character.BuffManager.cs +++ b/logic/GameClass/GameObj/Character.BuffManager.cs @@ -5,7 +5,7 @@ using Preparation.Utility; using Preparation.GameData; -namespace Preparation.GameObj +namespace GameClass.GameObj { public abstract partial class Character { @@ -73,10 +73,10 @@ private int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int } public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) - => AddBuff(new BuffValue(add), buffTime, BuffType.MoveSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.MoveSpeed, orgMoveSpeed, Constant.MaxSpeed, Constant.MinSpeed))); + => AddBuff(new BuffValue(add), buffTime, BuffType.MoveSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.MoveSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed))); public void AddAP(double add, int buffTime, Action SetNewAp, int orgAp) - => AddBuff(new BuffValue(add), buffTime, BuffType.AP, () => SetNewAp(ReCalculateFloatBuff(BuffType.AP, orgAp, Constant.MaxAP, Constant.MinAP))); + => AddBuff(new BuffValue(add), buffTime, BuffType.AP, () => SetNewAp(ReCalculateFloatBuff(BuffType.AP, orgAp, GameData.MaxAP, GameData.MinAP))); public void ChangeCD(double discount, int buffTime, Action SetNewCD, int orgCD) => AddBuff(new BuffValue(discount), buffTime, BuffType.CD, () => SetNewCD(ReCalculateFloatBuff(BuffType.CD, orgCD, int.MaxValue, 1))); diff --git a/logic/GameClass/GameObj/Character.SkillManager.cs b/logic/GameClass/GameObj/Character.SkillManager.cs new file mode 100644 index 00000000..2b7e3008 --- /dev/null +++ b/logic/GameClass/GameObj/Character.SkillManager.cs @@ -0,0 +1,31 @@ +using GameClass.Skill; + +namespace GameClass.GameObj +{ + public partial class Character + { + private delegate bool ActiveSkill(Character player); //返回值:是否成功释放了技能 + private delegate void PassiveSkill(Character player); + ActiveSkill commonSkill; + public bool UseCommonSkill() + { + return commonSkill(this); + } + private bool isCommonSkillAvailable = true; //普通技能可用标志 + public bool IsCommonSkillAvailable + { + get => isCommonSkillAvailable; + set + { + lock (gameObjLock) + isCommonSkillAvailable = value; + } + } + PassiveSkill passiveSkill; + public void UsePassiveSkill() + { + passiveSkill(this); + return; + } + } +} diff --git a/logic/Preparation/GameObj/Character.cs b/logic/GameClass/GameObj/Character.cs similarity index 93% rename from logic/Preparation/GameObj/Character.cs rename to logic/GameClass/GameObj/Character.cs index 8f7b52a8..9cfd3513 100644 --- a/logic/Preparation/GameObj/Character.cs +++ b/logic/GameClass/GameObj/Character.cs @@ -2,7 +2,7 @@ using Preparation.Interface; using Preparation.Utility; -namespace Preparation.GameObj +namespace GameClass.GameObj { public abstract partial class Character : GameObj, ICharacter // 负责人LHR摆烂中...该文件下抽象部分类已基本完工,剩下的在buffmanager里写 { @@ -27,25 +27,22 @@ private set } } } - public int orgCD { get; protected set; } - - private bool isCommonSkillAvailable = true; //普通技能可用标志 - public bool IsCommonSkillAvailable - { - get => isCommonSkillAvailable; - set - { - lock(gameObjLock) - isCommonSkillAvailable = 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; + public int HP + { + get => hp; + set + { + lock (gameObjLock) + hp = value; + } + } private int deathCount = 0; public int DeathCount => deathCount; // 玩家的死亡次数 @@ -70,7 +67,7 @@ private set private int attackRange; public int AttackRange => attackRange; - private double vampire = 0; // 回血率:0-1之间 + private double vampire; // 回血率:0-1之间 public double Vampire { get => vampire; @@ -87,6 +84,8 @@ public double Vampire vampire = value; } } + public double oriVampire = 0; + private int level = 1; public int Level { @@ -107,13 +106,6 @@ public Bullet BulletOfPlayer bulletOfPlayer = value; } } - - private delegate bool CommonSkill(Character player); //返回是否成功释放 - CommonSkill commonSkill; - public bool UseCommonSkill() - { - return commonSkill(this); - } /*private Prop? propInventory; public Prop? PropInventory //持有的道具 { @@ -379,20 +371,20 @@ private void TryActivatingLIFE() #endregion public override void Reset() { - /*AddDeathCount(); + AddDeathCount(); base.Reset(); this.moveSpeed = OrgMoveSpeed; hp = MaxHp; ap = OrgAp; PropInventory = null; bulletNum = maxBulletNum / 2; - buffManeger.ClearAll();*/ + buffManeger.ClearAll(); } public override bool IsRigid => true; public override ShapeType Shape => ShapeType.Circle; protected override bool IgnoreCollideExecutor(IGameObj targetObj) { - /*if (targetObj is BirthPoint && object.ReferenceEquals(((BirthPoint)targetObj).Parent, this)) // 自己的出生点可以忽略碰撞 + if (targetObj is BirthPoint && object.ReferenceEquals(((BirthPoint)targetObj).Parent, this)) // 自己的出生点可以忽略碰撞 { return true; } @@ -400,7 +392,7 @@ protected override bool IgnoreCollideExecutor(IGameObj targetObj) { return true; } - return false;*/ + return false; } public Character(XYPosition initPos, int initRadius, PlaceType initPlace,int initSpeed) :base(initPos,initRadius,initPlace) { diff --git a/logic/Preparation/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs similarity index 99% rename from logic/Preparation/GameObj/GameObj.cs rename to logic/GameClass/GameObj/GameObj.cs index 4d52cfdd..27b21a53 100644 --- a/logic/Preparation/GameObj/GameObj.cs +++ b/logic/GameClass/GameObj/GameObj.cs @@ -1,7 +1,7 @@ using Preparation.Interface; using Preparation.Utility; -namespace Preparation.GameObj +namespace GameClass.GameObj { /// /// 一切游戏元素的总基类,与THUAI4不同,继承IMoveable接口(出于一切物体其实都是可运动的指导思想)——LHR diff --git a/logic/Preparation/GameObj/Grass.cs b/logic/GameClass/GameObj/Grass.cs similarity index 88% rename from logic/Preparation/GameObj/Grass.cs rename to logic/GameClass/GameObj/Grass.cs index f98a58ed..019af8ba 100644 --- a/logic/Preparation/GameObj/Grass.cs +++ b/logic/GameClass/GameObj/Grass.cs @@ -2,14 +2,14 @@ using Preparation.Utility; using Preparation.GameData; -namespace Preparation.GameObj +namespace GameClass.GameObj { /// /// 草丛 /// public abstract class Grass : GameObj { - public Grass(XYPosition initPos) : base(initPos, Constant.numOfPosGridPerCell, PlaceType.Land) + public Grass(XYPosition initPos) : base(initPos, GameData.numOfPosGridPerCell, PlaceType.Land) { this.CanMove = false; this.Type = GameObjType.Grass; diff --git a/logic/Preparation/GameObj/Map.cs b/logic/GameClass/GameObj/Map.cs similarity index 55% rename from logic/Preparation/GameObj/Map.cs rename to logic/GameClass/GameObj/Map.cs index 88d6881e..571361a9 100644 --- a/logic/Preparation/GameObj/Map.cs +++ b/logic/GameClass/GameObj/Map.cs @@ -4,7 +4,7 @@ using Preparation.Utility; using Preparation.GameData; -namespace Preparation.GameObj +namespace GameClass.GameObj { public partial class Map:IMap { @@ -21,11 +21,14 @@ public partial class Map:IMap public ReaderWriterLockSlim ObjListLock => objListLock; public bool IsWall(XYPosition pos) { - return MapInfo.defaultMap[pos.x / Constant.numOfPosGridPerCell, pos.y / Constant.numOfPosGridPerCell] == 1; + return MapInfo.defaultMap[pos.x / GameData.numOfPosGridPerCell, pos.y / GameData.numOfPosGridPerCell] == 1; } - public bool OutOfBound(XYPosition pos) + public bool IsOutOfBound(IGameObj obj) { - return pos.x >= Constant.lengthOfMap || pos.x <= 0 || pos.y >= Constant.lengthOfMap || pos.y <= 0; + return obj.Position.x >= GameData.lengthOfMap - obj.Radius + || obj.Position.x <= obj.Radius + || obj.Position.y >= GameData.lengthOfMap - obj.Radius + || obj.Position.y <= obj.Radius; } public IOutOfBound GetOutOfBound(XYPosition pos) { @@ -33,13 +36,13 @@ public IOutOfBound GetOutOfBound(XYPosition pos) } public IGameObj GetCell(XYPosition pos) { - if (MapInfo.defaultMap[pos.x / Constant.numOfPosGridPerCell, pos.y / Constant.numOfPosGridPerCell] == 1) + if (MapInfo.defaultMap[pos.x / GameData.numOfPosGridPerCell, pos.y / GameData.numOfPosGridPerCell] == 1) return new Wall(pos); - else if (MapInfo.defaultMap[pos.x / Constant.numOfPosGridPerCell, pos.y / Constant.numOfPosGridPerCell] == 2) + else if (MapInfo.defaultMap[pos.x / GameData.numOfPosGridPerCell, pos.y / GameData.numOfPosGridPerCell] == 2) return new Grass1(pos); - else if (MapInfo.defaultMap[pos.x / Constant.numOfPosGridPerCell, pos.y / Constant.numOfPosGridPerCell] == 3) + else if (MapInfo.defaultMap[pos.x / GameData.numOfPosGridPerCell, pos.y / GameData.numOfPosGridPerCell] == 3) return new Grass2(pos); - else if (MapInfo.defaultMap[pos.x / Constant.numOfPosGridPerCell, pos.y / Constant.numOfPosGridPerCell] == 4) + else if (MapInfo.defaultMap[pos.x / GameData.numOfPosGridPerCell, pos.y / GameData.numOfPosGridPerCell] == 4) return new Grass3(pos); else return new OutOfBoundBlock(pos); } diff --git a/logic/Preparation/GameObj/MapGameTimer.cs b/logic/GameClass/GameObj/MapGameTimer.cs similarity index 95% rename from logic/Preparation/GameObj/MapGameTimer.cs rename to logic/GameClass/GameObj/MapGameTimer.cs index 684e6998..80b8cf2d 100644 --- a/logic/Preparation/GameObj/MapGameTimer.cs +++ b/logic/GameClass/GameObj/MapGameTimer.cs @@ -1,7 +1,7 @@ using System.Threading; using Preparation.Interface; -namespace Preparation.GameObj +namespace GameClass.GameObj { public partial class Map { diff --git a/logic/Preparation/GameObj/MapInfo.cs b/logic/GameClass/GameObj/MapInfo.cs similarity index 98% rename from logic/Preparation/GameObj/MapInfo.cs rename to logic/GameClass/GameObj/MapInfo.cs index e6da5b59..6a6dfb86 100644 --- a/logic/Preparation/GameObj/MapInfo.cs +++ b/logic/GameClass/GameObj/MapInfo.cs @@ -1,7 +1,7 @@ using Preparation.Utility; using Preparation.GameData; -namespace Preparation.GameObj +namespace GameClass.GameObj { public static class MapInfo { @@ -12,7 +12,7 @@ public static class MapInfo /// public static PlaceType GetPlaceType(GameObj obj) { - uint type = defaultMap[obj.Position.x / Constant.numOfPosGridPerCell, obj.Position.y / Constant.numOfPosGridPerCell]; + uint type = defaultMap[obj.Position.x / GameData.numOfPosGridPerCell, obj.Position.y / GameData.numOfPosGridPerCell]; if (type == 1) return PlaceType.Grass1; else if (type == 2) diff --git a/logic/Preparation/GameObj/ObjOfCharacter.cs b/logic/GameClass/GameObj/ObjOfCharacter.cs similarity index 95% rename from logic/Preparation/GameObj/ObjOfCharacter.cs rename to logic/GameClass/GameObj/ObjOfCharacter.cs index 096ebd4d..008188fb 100644 --- a/logic/Preparation/GameObj/ObjOfCharacter.cs +++ b/logic/GameClass/GameObj/ObjOfCharacter.cs @@ -1,7 +1,7 @@ using Preparation.Interface; using Preparation.Utility; -namespace Preparation.GameObj +namespace GameClass.GameObj { /// /// 所有物,玩家可以存进“物品栏”的东西 diff --git a/logic/Preparation/GameObj/OutOfBoundBlock.cs b/logic/GameClass/GameObj/OutOfBoundBlock.cs similarity index 94% rename from logic/Preparation/GameObj/OutOfBoundBlock.cs rename to logic/GameClass/GameObj/OutOfBoundBlock.cs index c8657ab2..96088d47 100644 --- a/logic/Preparation/GameObj/OutOfBoundBlock.cs +++ b/logic/GameClass/GameObj/OutOfBoundBlock.cs @@ -1,7 +1,7 @@ using Preparation.Interface; using Preparation.Utility; -namespace Preparation.GameObj +namespace GameClass.GameObj { /// /// 逻辑墙 diff --git a/logic/Preparation/GameObj/Prop.cs b/logic/GameClass/GameObj/Prop.cs similarity index 99% rename from logic/Preparation/GameObj/Prop.cs rename to logic/GameClass/GameObj/Prop.cs index 038130e3..30fa058c 100644 --- a/logic/Preparation/GameObj/Prop.cs +++ b/logic/GameClass/GameObj/Prop.cs @@ -1,7 +1,7 @@ using Preparation.Interface; using Preparation.Utility; -namespace Preparation.GameObj +namespace GameClass.GameObj { public abstract class Prop : ObjOfCharacter //LHR摆烂中...抽象类及所有增益道具已写完 { diff --git a/logic/Preparation/GameObj/Wall.cs b/logic/GameClass/GameObj/Wall.cs similarity index 70% rename from logic/Preparation/GameObj/Wall.cs rename to logic/GameClass/GameObj/Wall.cs index 4ff9df38..5314bae0 100644 --- a/logic/Preparation/GameObj/Wall.cs +++ b/logic/GameClass/GameObj/Wall.cs @@ -1,15 +1,14 @@ -using Preparation.Interface; -using Preparation.Utility; +using Preparation.Utility; using Preparation.GameData; -namespace Preparation.GameObj +namespace GameClass.GameObj { /// /// 墙体 /// public class Wall : GameObj { - public Wall(XYPosition initPos) : base(initPos, Constant.numOfPosGridPerCell, PlaceType.Land) + public Wall(XYPosition initPos) : base(initPos, GameData.numOfPosGridPerCell, PlaceType.Land) { this.CanMove = false; this.Type = GameObjType.Wall; diff --git a/logic/Preparation/Skill/CommonSkill.cs b/logic/GameClass/Skill/CommonSkill.cs similarity index 63% rename from logic/Preparation/Skill/CommonSkill.cs rename to logic/GameClass/Skill/CommonSkill.cs index f22a6229..e3e70156 100644 --- a/logic/Preparation/Skill/CommonSkill.cs +++ b/logic/GameClass/Skill/CommonSkill.cs @@ -1,13 +1,13 @@ -using Preparation.GameObj; +using GameClass.GameObj; using System.Threading; using Preparation.Utility; using Preparation.GameData; -namespace Preparation.Skill +namespace GameClass.Skill { public class BecomeVampire: CommonSkill //化身吸血鬼:1*标准技能cd,1*标准持续时间 { - public override int CD => Constant.commonSkillCD; + public override int CD => GameData.commonSkillCD; public override bool SkillEffect(Character player) { if (player.IsCommonSkillAvailable) @@ -20,11 +20,11 @@ public override bool SkillEffect(Character player) player.Vampire = 1.0; player.IsCommonSkillAvailable = false; } - Debugger.Output(player, "become vampire!"); - Thread.Sleep(Constant.commonSkillTime); + Debugger.Output(player, "becomes vampire!"); + Thread.Sleep(GameData.commonSkillTime); lock (player.SkillLock) { - player.Vampire = 0; + player.Vampire = player.oriVampire; } Debugger.Output(player, "return to normal."); Thread.Sleep(CD); @@ -46,7 +46,7 @@ public override bool SkillEffect(Character player) } public class BecomeAssassin: CommonSkill //化身刺客,隐身:1*标准技能cd,1*标准持续时间 { - public override int CD => Constant.commonSkillCD; + public override int CD => GameData.commonSkillCD; public override bool SkillEffect(Character player) { if (player.IsCommonSkillAvailable) @@ -59,8 +59,8 @@ public override bool SkillEffect(Character player) player.Place = PlaceType.Invisible; player.IsCommonSkillAvailable = false; } - Debugger.Output(player, "become assassin!"); - Thread.Sleep(Constant.commonSkillTime); + Debugger.Output(player, "becomes assassin!"); + Thread.Sleep(GameData.commonSkillTime); lock (player.SkillLock) { player.Place = MapInfo.GetPlaceType(player); @@ -85,7 +85,7 @@ public override bool SkillEffect(Character player) } public class NuclearWeapon : CommonSkill //核武器:1*标准技能cd,0.5*标准持续时间 { - public override int CD => Constant.commonSkillCD; + public override int CD => GameData.commonSkillCD; public override bool SkillEffect(Character player) { if (player.IsCommonSkillAvailable) @@ -96,11 +96,11 @@ public override bool SkillEffect(Character player) Bullet b = player.BulletOfPlayer; lock (player.SkillLock) { - player.BulletOfPlayer = new AtomBomb(player, Constant.bulletRadius, b.MoveSpeed, (int)(1.5 * b.AP)); + player.BulletOfPlayer = new AtomBomb(player, GameData.bulletRadius, b.MoveSpeed, (int)(1.5 * b.AP)); player.IsCommonSkillAvailable = false; } - Debugger.Output(player, "become assassin!"); - Thread.Sleep(Constant.commonSkillTime / 2); + Debugger.Output(player, "uses atombomb!"); + Thread.Sleep(GameData.commonSkillTime / 2); lock (player.SkillLock) { player.BulletOfPlayer = b; @@ -123,4 +123,43 @@ public override bool SkillEffect(Character player) } } } + public class SuperFast : CommonSkill //3倍速:1*标准技能cd,1*标准持续时间 + { + public override int CD => GameData.commonSkillCD; + public override bool SkillEffect(Character player) + { + if (player.IsCommonSkillAvailable) + { + new Thread + (() => + { + lock (player.SkillLock) + { + player.SetMoveSpeed(3 * player.OrgMoveSpeed); + player.IsCommonSkillAvailable = false; + } + Debugger.Output(player, "moves very fast!"); + Thread.Sleep(GameData.commonSkillTime); + lock (player.SkillLock) + { + player.SetMoveSpeed(player.OrgMoveSpeed); + } + Debugger.Output(player, "return to normal."); + Thread.Sleep(CD); + lock (player.SkillLock) + { + player.IsCommonSkillAvailable = true; + } + } + ) + { IsBackground = true }.Start(); + return true; + } + else + { + Debugger.Output(player, "CommonSkill is cooling down!"); + return false; + } + } + } } diff --git a/logic/GameClass/Skill/PassiveSkill.cs b/logic/GameClass/Skill/PassiveSkill.cs new file mode 100644 index 00000000..e351ef85 --- /dev/null +++ b/logic/GameClass/Skill/PassiveSkill.cs @@ -0,0 +1,137 @@ +using System; +using System.Threading; +using GameClass.GameObj; +using Preparation.GameData; +using Preparation.Utility; +using Timothy.FrameRateTask; + +namespace GameClass.Skill //被动技能开局时就释放,持续到游戏结束 +{ + public class RecoverAfterBattle:PassiveSkill //脱战回血 + { + public override void SkillEffect(Character player) + { + const int recoverDegree = 1; //每帧回复血量 + int nowHP = player.HP; + int lastHP = nowHP; + long waitTime = 0; + const long interval = 20000; //每隔interval时间不受伤害,角色即开始回血 + new Thread + ( + () => + { + new FrameRateTaskExecutor + ( + () => true, + ()=> + { + lastHP = nowHP; //lastHP等于上一帧的HP + nowHP = player.HP; //nowHP更新为这一帧的HP + if (lastHP > nowHP) //这一帧扣血了 + { + waitTime = 0; + } + else if (waitTime < interval) + { + waitTime += GameData.frameDuration; + } + + if (waitTime >= interval) //回复时,每帧(50ms)回复1,即1s回复20。 + player.TryAddHp(recoverDegree); + }, + timeInterval: GameData.frameDuration, + () => 0, + maxTotalDuration: GameData.gameDuration + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + TimeExceedAction = b => + { + if (b) Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!"); + +#if DEBUG + else + { + Console.WriteLine("Debug info: passive skill time exceeds for once."); + } +#endif + } + }.Start(); + } + ) + { IsBackground=true }.Start(); + } + } + public class SpeedUpWhenLeavingGrass:PassiveSkill //出草丛时加速并免疫减速,但隐身时出草丛不会有该效果 + { + public override void SkillEffect(Character player) + { + PlaceType nowPlace = player.Place; + PlaceType lastPlace = nowPlace; + bool beginSpeedUp = false; + int speedUpTimes = 0; + const int maxSpeedUpTimes = (int)(2000 / GameData.frameDuration); //加速时间:2s + new Thread + ( + () => + { + new FrameRateTaskExecutor + ( + () => true, + () => + { + lastPlace = nowPlace; + nowPlace = player.Place; + if ((lastPlace == PlaceType.Grass1 || lastPlace == PlaceType.Grass2 || lastPlace == PlaceType.Grass3) && nowPlace == PlaceType.Land) + { + beginSpeedUp = true; + speedUpTimes = 0; + } + if(beginSpeedUp) + { + if (speedUpTimes <= maxSpeedUpTimes) + { + speedUpTimes++; + player.SetMoveSpeed(player.OrgMoveSpeed * 3); //3倍速 + } + else + { + speedUpTimes = 0; + beginSpeedUp = false; + player.SetMoveSpeed(player.OrgMoveSpeed); + } + } + }, + timeInterval: GameData.frameDuration, + () => 0, + maxTotalDuration: GameData.gameDuration + ) + { + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + TimeExceedAction = b => + { + if (b) Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!"); + +#if DEBUG + else + { + Console.WriteLine("Debug info: passive skill time exceeds for once."); + } +#endif + } + }.Start(); + } + ) + { IsBackground = true }.Start(); + } + } + public class Vampire:PassiveSkill //被动就是吸血 + { + public override void SkillEffect(Character player) + { + player.oriVampire = 0.1; + } + } +} diff --git a/logic/Preparation/Skill/Skill.cs b/logic/GameClass/Skill/Skill.cs similarity index 75% rename from logic/Preparation/Skill/Skill.cs rename to logic/GameClass/Skill/Skill.cs index 6077e60d..6c6054bc 100644 --- a/logic/Preparation/Skill/Skill.cs +++ b/logic/GameClass/Skill/Skill.cs @@ -1,13 +1,14 @@ -using Preparation.GameObj; +using GameClass.GameObj; -namespace Preparation.Skill +namespace GameClass.Skill { public abstract class PassiveSkill { - /* public abstract double AttackRange { get; } - public abstract double BulletBombRange { get; } - public abstract int MaxBulletNum { get; } - public abstract double BulletMoveSpeed { get; }*/ + /* public abstract double AttackRange { get; } + public abstract double BulletBombRange { get; } + public abstract int MaxBulletNum { get; } + public abstract double BulletMoveSpeed { get; }*/ + public abstract void SkillEffect(Character player); } public abstract class CommonSkill {/* diff --git a/logic/GameEngine/CollisionChecker.cs b/logic/GameEngine/CollisionChecker.cs index 1d04b6a8..683bf43b 100644 --- a/logic/GameEngine/CollisionChecker.cs +++ b/logic/GameEngine/CollisionChecker.cs @@ -20,7 +20,7 @@ internal class CollisionChecker XYPosition nextPos = obj.Position + Vector.Vector2XY(moveVec); if (!obj.IsRigid) { - if (gameMap.OutOfBound(obj.Position)) + if (gameMap.IsOutOfBound(obj)) return gameMap.GetOutOfBound(nextPos); return null; } @@ -98,7 +98,7 @@ public double FindMax(IMoveable obj, XYPosition nextPos, Vector moveVec) { maxOnlyConsiderWall = MaxMoveToSquare(obj, gameMap.GetCell(Vector.Vector2XY(desination) + obj.Position)); } - desination.length -= Constant.numOfPosGridPerCell / (Math.Abs(Math.Cos(desination.angle))); + desination.length -= GameData.numOfPosGridPerCell / (Math.Abs(Math.Cos(desination.angle))); } tmpMax = maxLen; diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs index 958df19c..a67b8a6e 100644 --- a/logic/GameEngine/MoveEngine.cs +++ b/logic/GameEngine/MoveEngine.cs @@ -1,6 +1,5 @@ using System; using System.Threading; -using Preparation.GameObj; using Preparation.Interface; using Preparation.Utility; using Timothy.FrameRateTask; @@ -54,11 +53,11 @@ private void MoveMax(IMoveable obj, Vector moveVec) /*由于四周是墙,所以人物永远不可能与越界方块碰撞*/ XYPosition nextPos = obj.Position + Vector.Vector2XY(moveVec); double maxLen = collisionChecker.FindMax(obj, nextPos, moveVec); - maxLen = Math.Min(maxLen, obj.MoveSpeed / Constant.numOfStepPerSecond); + maxLen = Math.Min(maxLen, obj.MoveSpeed / GameData.numOfStepPerSecond); obj.Move(new Vector(moveVec.angle, maxLen)); } - public void MoveObj(GameObj obj,int moveTime,double direction) + public void MoveObj(IMoveable obj,int moveTime,double direction) { new Thread ( @@ -80,7 +79,7 @@ public void MoveObj(GameObj obj,int moveTime,double direction) () => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting, () => { - moveVec.length = obj.MoveSpeed / Constant.numOfStepPerSecond ; + moveVec.length = obj.MoveSpeed / GameData.numOfStepPerSecond ; //越界情况处理:如果越界,则与越界方块碰撞 bool flag; //循环标志 @@ -96,7 +95,7 @@ public void MoveObj(GameObj obj,int moveTime,double direction) flag=true; break; case AfterCollision.Destroyed: - //Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); + Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); isDestroyed = true; return false; case AfterCollision.MoveMax: @@ -110,10 +109,10 @@ public void MoveObj(GameObj obj,int moveTime,double direction) return true; }, - Constant.numOfPosGridPerCell / Constant.numOfStepPerSecond, + GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond, () => { - int leftTime = moveTime % (Constant.numOfPosGridPerCell / Constant.numOfStepPerSecond); + int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond); bool flag; do { @@ -133,7 +132,7 @@ public void MoveObj(GameObj obj,int moveTime,double direction) flag = true; break; case AfterCollision.Destroyed: - //Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); + Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); isDestroyed = true; break; case AfterCollision.MoveMax: @@ -168,7 +167,7 @@ public void MoveObj(GameObj obj,int moveTime,double direction) Console.WriteLine("Debug info: Object moving time exceed for once."); } #endif - } + } }.Start(); } ).Start(); diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 4ef6aae0..cf05b407 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -1,6 +1,6 @@ -using System; -using System.Threading; -using Preparation.GameObj; +using System.Threading; +using GameClass.GameObj; +using Preparation.GameData; using Preparation.Utility; using GameEngine; @@ -26,15 +26,15 @@ private void BombOnePlayer(Bullet bullet,Character playerBeingShot) gameMap.PlayerListLock.ExitWriteLock(); } playerBeingShot.Reset(); - ((Character?)bullet.Parent)?.AddScore(Constant.addScoreWhenKillOneLevelPlayer); //给击杀者加分 + ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); //给击杀者加分 new Thread (() => { - Thread.Sleep(Constant.deadRestoreTime); + Thread.Sleep(GameData.deadRestoreTime); - playerBeingShot.AddShield(Constant.shieldTimeAtBirth); //复活加个盾 + playerBeingShot.AddShield(GameData.shieldTimeAtBirth); //复活加个盾 gameMap.PlayerListLock.EnterWriteLock(); try @@ -50,7 +50,7 @@ private void BombOnePlayer(Bullet bullet,Character playerBeingShot) playerBeingShot.IsResetting = false; } ) - { IsBackground = true }.Start();*/ + { IsBackground = true }.Start(); } } private void BulletBomb(Bullet bullet, GameObj? objBeingShot) @@ -60,7 +60,7 @@ private void BulletBomb(Bullet bullet, GameObj? objBeingShot) gameMap.ObjListLock.EnterWriteLock(); try { - foreach (Obj obj in gameMap.ObjList) + foreach (ObjOfCharacter obj in gameMap.ObjList) { if (obj.ID == bullet.ID) { @@ -75,7 +75,7 @@ private void BulletBomb(Bullet bullet, GameObj? objBeingShot) if(objBeingShot is Character) { BombOnePlayer(bullet, (Character)objBeingShot); - bullet.Parent.HP = (int)(bullet.Parent.HP + bullet.Parent.Vampire * bullet.Ap); //造成伤害根据吸血率来吸血 + bullet.Parent.HP = (int)(bullet.Parent.HP + bullet.Parent.Vampire * bullet.AP); //造成伤害根据吸血率来吸血 } /*else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。 { @@ -83,8 +83,21 @@ private void BulletBomb(Bullet bullet, GameObj? objBeingShot) }*/ } - //子弹爆炸 + //子弹爆炸会发生的事↓↓↓ + /* + 赶 + 紧 + 写 + 完 + 啊 + 啊 + 啊 + 啊 + ! + ! + ! + */ } } } diff --git a/logic/Gaming/Gaming.csproj b/logic/Gaming/Gaming.csproj index 536734df..22cd8ac9 100644 --- a/logic/Gaming/Gaming.csproj +++ b/logic/Gaming/Gaming.csproj @@ -6,6 +6,7 @@ + diff --git a/logic/Gaming/MoveManager.cs b/logic/Gaming/MoveManager.cs index 2ce5a31e..057090c3 100644 --- a/logic/Gaming/MoveManager.cs +++ b/logic/Gaming/MoveManager.cs @@ -1,5 +1,5 @@ using System; -using Preparation.GameObj; +using GameClass.GameObj; using GameEngine; namespace Gaming diff --git a/logic/Preparation/GameData/Constant.cs b/logic/Preparation/GameData/GameData.cs similarity index 91% rename from logic/Preparation/GameData/Constant.cs rename to logic/Preparation/GameData/GameData.cs index 340a6e0d..debca850 100644 --- a/logic/Preparation/GameData/Constant.cs +++ b/logic/Preparation/GameData/GameData.cs @@ -1,13 +1,14 @@ -using Preparation.GameObj; -using Preparation.Utility; +using Preparation.Utility; namespace Preparation.GameData { - public static class Constant + public static class GameData { public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 public const int numOfStepPerSecond = 20; // 每秒行走的步数 public const int lengthOfMap = 50000; // 地图长度 + public const long gameDuration = 600000; // 游戏时长600000ms = 10min + public const long frameDuration = 50; // 每帧时长 public const int MinSpeed = 1; //最小速度 public const int MaxSpeed = int.MaxValue; //最大速度 diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index 0b5f2b8b..fe4ef79b 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -7,5 +7,8 @@ public interface ICharacter:IGameObj { object PropLock { get; } public long TeamID { get; } + public int HP { get; set; } + public double Vampire { get; } + } } diff --git a/logic/Preparation/Interface/IMap.cs b/logic/Preparation/Interface/IMap.cs index 5d800d8f..211390da 100644 --- a/logic/Preparation/Interface/IMap.cs +++ b/logic/Preparation/Interface/IMap.cs @@ -12,7 +12,7 @@ public interface IMap ReaderWriterLockSlim PlayerListLock { get; } ReaderWriterLockSlim ObjListLock { get; } public bool IsWall(XYPosition pos); - public bool OutOfBound(XYPosition pos); + public bool IsOutOfBound(IGameObj obj); public IOutOfBound GetOutOfBound(XYPosition pos); //返回新建的一个OutOfBound对象 public IGameObj GetCell(XYPosition pos); //返回pos所在的cell } diff --git a/logic/Preparation/Skill/PassiveSkill.cs b/logic/Preparation/Skill/PassiveSkill.cs deleted file mode 100644 index 025d8823..00000000 --- a/logic/Preparation/Skill/PassiveSkill.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using Preparation.GameObj; -using Preparation.Utility; - -namespace Preparation.Skill -{ - /*public class FastShoot:PassiveSkill - { - public override double AttackRange => Constant.basicAttackRange * 0.8; - public override double BulletBombRange => Constant.basicBulletBombRange * 0.8; - public override int MaxBulletNum => Constant.basicMaxBulletNum; - public override double BulletMoveSpeed => Constant.basicBulletMoveSpeed * 2.0; - } - public class NuclearWeapon:PassiveSkill - { - public override double AttackRange => Constant.basicAttackRange * 1.2; - public override double BulletBombRange => Constant.basicBulletBombRange * 2; - public override int MaxBulletNum => Constant.basicMaxBulletNum - 2; - public override double BulletMoveSpeed => Constant.basicBulletMoveSpeed * 0.4; - } - public class BigEyes:PassiveSkill - { - public override double AttackRange => Constant.basicAttackRange * 2; - public override double BulletBombRange => Constant.basicBulletBombRange * 0.8; - public override int MaxBulletNum => Constant.basicMaxBulletNum; - public override double BulletMoveSpeed => Constant.basicBulletMoveSpeed * 0.4; - }*/ - -} diff --git a/logic/Preparation/Utility/EnumType.cs b/logic/Preparation/Utility/EnumType.cs index 986f95fc..1d06997b 100644 --- a/logic/Preparation/Utility/EnumType.cs +++ b/logic/Preparation/Utility/EnumType.cs @@ -1,6 +1,4 @@ -using Preparation.GameObj; -using Preparation.Interface; - + namespace Preparation.Utility { /// @@ -56,9 +54,9 @@ public enum PropType // 道具的类型 public enum PassiveSkillType // 被动技能 { Null = 0, - PSkill0 = 1, - PSkill1 = 2, - PSkill2 = 3, + RecoverAfterBattle = 1, + SpeedUpWhenLeavingGrass = 2, + Vampire = 3, PSkill3 = 4, PSkill4 = 5, PSkill5 = 6 @@ -66,10 +64,10 @@ public enum PassiveSkillType // 被动技能 public enum ActiveSkillType // 主动技能 { Null = 0, - ASkill0 = 1, - ASkill1 = 2, - ASkill2 = 3, - ASkill3 = 4, + BecomeVampire = 1, + BecomeAssassin = 2, + NuclearWeapon = 3, + SuperFast = 4, ASkill4 = 5, ASkill5 = 6 } diff --git a/logic/logic.sln b/logic/logic.sln index 6b6aa5b1..106ac0ca 100644 --- a/logic/logic.sln +++ b/logic/logic.sln @@ -1,4 +1,3 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 16 VisualStudioVersion = 16.0.31410.357 @@ -9,14 +8,23 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Preparation", "Preparation\ EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BE94BE7A-369D-4148-9E5E-5B00FE52C424}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FrameRateTask", "FrameRateTask\FrameRateTask.csproj", "{1307F310-A240-4E10-ACB2-5F187D70F74D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{29F82A42-BB11-4B10-AB67-3ADC3D022E81}" +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BE94BE7A-369D-4148-9E5E-5B00FE52C424}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + EndProjectSection +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "GameClass", "GameClass\GameClass.csproj", "{C46AFFCE-AC47-480B-A823-C1DB948AAE8D}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Gaming", "Gaming\Gaming.csproj", "{899D4146-B923-4C7D-A39E-F4D6372CF2C8}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{BDCAFA75-56F1-4892-B89C-4727A6D28A27}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -40,11 +48,18 @@ Global {1307F310-A240-4E10-ACB2-5F187D70F74D}.Debug|Any CPU.Build.0 = Debug|Any CPU {1307F310-A240-4E10-ACB2-5F187D70F74D}.Release|Any CPU.ActiveCfg = Release|Any CPU {1307F310-A240-4E10-ACB2-5F187D70F74D}.Release|Any CPU.Build.0 = Release|Any CPU - {29F82A42-BB11-4B10-AB67-3ADC3D022E81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {29F82A42-BB11-4B10-AB67-3ADC3D022E81}.Debug|Any CPU.Build.0 = Debug|Any CPU - {29F82A42-BB11-4B10-AB67-3ADC3D022E81}.Release|Any CPU.ActiveCfg = Release|Any CPU - {29F82A42-BB11-4B10-AB67-3ADC3D022E81}.Release|Any CPU.Build.0 = Release|Any CPU - + {C46AFFCE-AC47-480B-A823-C1DB948AAE8D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C46AFFCE-AC47-480B-A823-C1DB948AAE8D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C46AFFCE-AC47-480B-A823-C1DB948AAE8D}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C46AFFCE-AC47-480B-A823-C1DB948AAE8D}.Release|Any CPU.Build.0 = Release|Any CPU + {899D4146-B923-4C7D-A39E-F4D6372CF2C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {899D4146-B923-4C7D-A39E-F4D6372CF2C8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {899D4146-B923-4C7D-A39E-F4D6372CF2C8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {899D4146-B923-4C7D-A39E-F4D6372CF2C8}.Release|Any CPU.Build.0 = Release|Any CPU + {BDCAFA75-56F1-4892-B89C-4727A6D28A27}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BDCAFA75-56F1-4892-B89C-4727A6D28A27}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BDCAFA75-56F1-4892-B89C-4727A6D28A27}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BDCAFA75-56F1-4892-B89C-4727A6D28A27}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE