| @@ -4,44 +4,48 @@ using System; | |||
| namespace GameClass.GameObj | |||
| { | |||
| public abstract class Bullet : ObjOfCharacter | |||
| internal sealed class CommonAttackOfGhost : Bullet | |||
| { | |||
| /// <summary> | |||
| /// //攻击力 | |||
| /// </summary> | |||
| public abstract int AP { get; } | |||
| public abstract int Speed { get; } | |||
| private readonly bool hasSpear; | |||
| /// <summary> | |||
| /// 是否有矛 | |||
| /// </summary> | |||
| public bool HasSpear => hasSpear; | |||
| /// <summary> | |||
| /// 与THUAI4不同的一个攻击判定方案,通过这个函数判断爆炸时能否伤害到target | |||
| /// </summary> | |||
| /// <param name="target">被尝试攻击者</param> | |||
| /// <returns>是否可以攻击到</returns> | |||
| public abstract bool CanAttack(GameObj target); | |||
| protected override bool IgnoreCollideExecutor(IGameObj targetObj) | |||
| public CommonAttackOfGhost(Character player, int radius = GameData.bulletRadius) : | |||
| base(player, radius) | |||
| { | |||
| } | |||
| public override double BulletBombRange => 0; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange; | |||
| public override int AP => GameData.basicApOfGhost; | |||
| public override int Speed => GameData.basicBulletMoveSpeed; | |||
| public override bool IsToBomb => false; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| if (targetObj.Type == GameObjType.BirthPoint || targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet) | |||
| return true; | |||
| return false; | |||
| } | |||
| public Bullet(Character player, int radius) : | |||
| base(player.Position, radius, PlaceType.Null, GameObjType.Bullet) | |||
| public override BulletType TypeOfBullet => BulletType.CommonAttackOfGhost; | |||
| } | |||
| internal sealed class FlyingKnife : Bullet | |||
| { | |||
| public FlyingKnife(Character player, int radius = GameData.bulletRadius) : | |||
| base(player, radius) | |||
| { | |||
| } | |||
| public override double BulletBombRange => 0; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange * 13; | |||
| public override int AP => GameData.basicApOfGhost / 3 * 7; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2; | |||
| public override bool IsToBomb => true; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| this.CanMove = true; | |||
| this.moveSpeed = this.Speed; | |||
| this.hasSpear = player.HasSpear; | |||
| this.Parent = player; | |||
| // 圆形攻击范围 | |||
| return XY.Distance(this.Position, target.Position) <= BulletBombRange; | |||
| } | |||
| public override bool IsRigid => true; // 默认为true | |||
| public override ShapeType Shape => ShapeType.Circle; // 默认为圆形 | |||
| public abstract BulletType TypeOfBullet { get; } | |||
| public override BulletType TypeOfBullet => BulletType.FlyingKnife; | |||
| } | |||
| internal sealed class AtomBomb : Bullet | |||
| @@ -50,10 +54,13 @@ namespace GameClass.GameObj | |||
| base(player, radius) | |||
| { | |||
| } | |||
| public const double BulletBombRange = GameData.basicBulletBombRange / 3 * 7; | |||
| public const double BulletAttackRange = GameData.basicAttackRange / 9 * 7; | |||
| public override int AP => GameData.basicAp / 3 * 7; | |||
| public override double BulletBombRange => GameData.basicBulletBombRange / 3 * 7; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange / 9 * 7; | |||
| public override int AP => GameData.basicApOfGhost / 3 * 7; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 3 * 2; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| // 圆形攻击范围 | |||
| @@ -61,6 +68,7 @@ namespace GameClass.GameObj | |||
| } | |||
| public override BulletType TypeOfBullet => BulletType.AtomBomb; | |||
| } | |||
| internal sealed class OrdinaryBullet : Bullet // 1倍攻击范围,1倍攻击力,一倍速 | |||
| @@ -69,10 +77,13 @@ namespace GameClass.GameObj | |||
| base(player, radius) | |||
| { | |||
| } | |||
| public const double BulletBombRange = GameData.basicBulletBombRange / 6 * 5; | |||
| public const double BulletAttackRange = GameData.basicAttackRange / 2; | |||
| public override int AP => GameData.basicAp / 6 * 5; | |||
| public override double BulletBombRange => GameData.basicBulletBombRange / 6 * 5; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange / 2; | |||
| public override int AP => GameData.basicApOfGhost / 6 * 5; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 6 * 5; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| // 圆形攻击范围 | |||
| @@ -88,10 +99,13 @@ namespace GameClass.GameObj | |||
| base(player, radius) | |||
| { | |||
| } | |||
| public const double BulletBombRange = GameData.basicBulletBombRange / 4 * 2; | |||
| public const double BulletAttackRange = GameData.basicAttackRange; | |||
| public override int AP => (int)(0.5 * GameData.basicAp); | |||
| public override double BulletBombRange => GameData.basicBulletBombRange / 4 * 2; | |||
| public override double BulletAttackRange => GameData.basicAttackShortRange; | |||
| public override int AP => (int)(0.5 * GameData.basicApOfGhost); | |||
| public override int Speed => 5 * GameData.basicBulletMoveSpeed / 3; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| @@ -108,10 +122,13 @@ namespace GameClass.GameObj | |||
| base(player, radius) | |||
| { | |||
| } | |||
| public const double BulletBombRange = GameData.basicBulletBombRange / 3 * 4; | |||
| public const double BulletAttackRange = 0.1 * GameData.basicAttackRange; | |||
| public override int AP => GameData.basicAp / 3 * 2; | |||
| public override double BulletBombRange => GameData.basicBulletBombRange / 3 * 4; | |||
| public override double BulletAttackRange => 0.1 * GameData.basicAttackShortRange; | |||
| public override int AP => GameData.basicApOfGhost / 3 * 2; | |||
| public override int Speed => GameData.basicBulletMoveSpeed / 3; | |||
| public override int Backswing => GameData.basicBackswing; | |||
| public override int RecoveryFromHit => GameData.basicRecoveryFromHit; | |||
| public override bool IsToBomb => true; | |||
| public override bool CanAttack(GameObj target) | |||
| { | |||
| @@ -165,73 +182,5 @@ namespace GameClass.GameObj | |||
| public override BulletType TypeOfBullet => BulletType.LineBullet; | |||
| } | |||
| public static class BulletFactory | |||
| { | |||
| public static Bullet? GetBullet(Character character) | |||
| { | |||
| Bullet? newBullet = null; | |||
| switch (character.BulletOfPlayer) | |||
| { | |||
| case BulletType.AtomBomb: | |||
| newBullet = new AtomBomb(character); | |||
| break; | |||
| case BulletType.LineBullet: | |||
| newBullet = new LineBullet(character); | |||
| break; | |||
| case BulletType.FastBullet: | |||
| newBullet = new FastBullet(character); | |||
| break; | |||
| case BulletType.OrdinaryBullet: | |||
| newBullet = new OrdinaryBullet(character); | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| return newBullet; | |||
| } | |||
| public static int BulletRadius(BulletType bulletType) | |||
| { | |||
| switch (bulletType) | |||
| { | |||
| case BulletType.AtomBomb: | |||
| case BulletType.LineBullet: | |||
| case BulletType.FastBullet: | |||
| case BulletType.OrdinaryBullet: | |||
| default: | |||
| return GameData.bulletRadius; | |||
| } | |||
| } | |||
| public static double BulletAttackRange(BulletType bulletType) | |||
| { | |||
| switch (bulletType) | |||
| { | |||
| case BulletType.AtomBomb: | |||
| return AtomBomb.BulletAttackRange; | |||
| case BulletType.LineBullet: | |||
| return LineBullet.BulletAttackRange; | |||
| case BulletType.FastBullet: | |||
| return FastBullet.BulletAttackRange; | |||
| case BulletType.OrdinaryBullet: | |||
| return OrdinaryBullet.BulletAttackRange; | |||
| default: | |||
| return 0; | |||
| } | |||
| } | |||
| public static double BulletBombRange(BulletType bulletType) | |||
| { | |||
| switch (bulletType) | |||
| { | |||
| case BulletType.AtomBomb: | |||
| return AtomBomb.BulletBombRange; | |||
| case BulletType.LineBullet: | |||
| return LineBullet.BulletBombRange; | |||
| case BulletType.FastBullet: | |||
| return FastBullet.BulletBombRange; | |||
| case BulletType.OrdinaryBullet: | |||
| return OrdinaryBullet.BulletBombRange; | |||
| default: | |||
| return 0; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -0,0 +1,7 @@ | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System; | |||
| namespace GameClass.GameObj | |||
| { | |||
| } | |||
| @@ -0,0 +1,89 @@ | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System; | |||
| namespace GameClass.GameObj | |||
| { | |||
| public abstract class Bullet : ObjOfCharacter | |||
| { | |||
| /// <summary> | |||
| /// //攻击力 | |||
| /// </summary> | |||
| public abstract double BulletBombRange{ get; } | |||
| public abstract double BulletAttackRange{ get; } | |||
| public abstract int AP { get; } | |||
| public abstract int Speed { get; } | |||
| public abstract bool IsToBomb { get; } | |||
| public abstract int Backswing { get; } | |||
| public abstract int RecoveryFromHit { get; } | |||
| private readonly bool hasSpear; | |||
| /// <summary> | |||
| /// 是否有矛 | |||
| /// </summary> | |||
| public bool HasSpear => hasSpear; | |||
| /// <summary> | |||
| /// 与THUAI4不同的一个攻击判定方案,通过这个函数判断爆炸时能否伤害到target | |||
| /// </summary> | |||
| /// <param name="target">被尝试攻击者</param> | |||
| /// <returns>是否可以攻击到</returns> | |||
| public abstract bool CanAttack(GameObj target); | |||
| protected override bool IgnoreCollideExecutor(IGameObj targetObj) | |||
| { | |||
| if (targetObj.Type == GameObjType.BirthPoint || targetObj.Type == GameObjType.Prop || targetObj.Type == GameObjType.Bullet) | |||
| return true; | |||
| return false; | |||
| } | |||
| public Bullet(Character player, int radius) : | |||
| base(player.Position, radius, PlaceType.Null, GameObjType.Bullet) | |||
| { | |||
| this.CanMove = true; | |||
| this.moveSpeed = this.Speed; | |||
| this.hasSpear = player.HasSpear; | |||
| this.Parent = player; | |||
| } | |||
| public override bool IsRigid => true; // 默认为true | |||
| public override ShapeType Shape => ShapeType.Circle; // 默认为圆形 | |||
| public abstract BulletType TypeOfBullet { get; } | |||
| } | |||
| public static class BulletFactory | |||
| { | |||
| public static Bullet? GetBullet(Character character) | |||
| { | |||
| Bullet? newBullet = null; | |||
| switch (character.BulletOfPlayer) | |||
| { | |||
| case BulletType.AtomBomb: | |||
| newBullet = new AtomBomb(character); | |||
| break; | |||
| case BulletType.LineBullet: | |||
| newBullet = new LineBullet(character); | |||
| break; | |||
| case BulletType.FastBullet: | |||
| newBullet = new FastBullet(character); | |||
| break; | |||
| case BulletType.OrdinaryBullet: | |||
| newBullet = new OrdinaryBullet(character); | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| return newBullet; | |||
| } | |||
| public static int BulletRadius(BulletType bulletType) | |||
| { | |||
| switch (bulletType) | |||
| { | |||
| case BulletType.AtomBomb: | |||
| case BulletType.LineBullet: | |||
| case BulletType.FastBullet: | |||
| case BulletType.OrdinaryBullet: | |||
| default: | |||
| return GameData.bulletRadius; | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -19,15 +19,18 @@ namespace GameClass.GameObj | |||
| { | |||
| return commonSkill(this); | |||
| } | |||
| private int timeUntilCommonSkillAvailable = 0; // 还剩多少时间可以使用普通技能 | |||
| public int TimeUntilCommonSkillAvailable | |||
| private Dictionary<ActiveSkillType, int> TimeUntilActiveSkillAvailable { get; set; } | |||
| public bool SetTimeUntilActiveSkillAvailable(ActiveSkillType activeSkillType, int timeUntilActiveSkillAvailable) | |||
| { | |||
| get => timeUntilCommonSkillAvailable; | |||
| set | |||
| lock (gameObjLock) | |||
| if (TimeUntilActiveSkillAvailable.ContainsKey(activeSkillType)) | |||
| { | |||
| lock (gameObjLock) | |||
| timeUntilCommonSkillAvailable = value < 0 ? 0 : value; | |||
| TimeUntilActiveSkillAvailable[activeSkillType] = (timeUntilActiveSkillAvailable > 0) ? timeUntilActiveSkillAvailable : 0; | |||
| return true; | |||
| } | |||
| return false; | |||
| } | |||
| readonly CharacterPassiveSkill passiveSkill; | |||
| @@ -41,14 +44,14 @@ namespace GameClass.GameObj | |||
| { | |||
| return this.characterType switch | |||
| { | |||
| CharacterType.Assassin => true, | |||
| CharacterType.Vampire => true, | |||
| this.CharacterType.Assassin => true, | |||
| this.CharacterType.Vampire => true, | |||
| CharacterType.Null => false, | |||
| CharacterType.RecoverAfterBattle => false, | |||
| CharacterType.SpeedUpWhenLeavingGrass => false, | |||
| CharacterType.PSkill4 => false, | |||
| CharacterType.PSkill5 => false, | |||
| this.CharacterType.Null => false, | |||
| this.CharacterType.RecoverAfterBattle => false, | |||
| this.CharacterType.SpeedUpWhenLeavingGrass => false, | |||
| this.CharacterType.PSkill4 => false, | |||
| this.CharacterType.PSkill5 => false, | |||
| _ => false, | |||
| }; | |||
| } | |||
| @@ -61,19 +64,19 @@ namespace GameClass.GameObj | |||
| this.propInventory = null; | |||
| this.buffManeger = new BuffManeger(); | |||
| IPassiveSkill pSkill; | |||
| ICommonSkill cSkill; | |||
| IActiveSkill cSkill; | |||
| switch (characterType) | |||
| { | |||
| case CharacterType.Assassin: | |||
| pSkill = new(); | |||
| case this.CharacterType.Assassin: | |||
| pSkill = null; | |||
| break; | |||
| case CharacterType.RecoverAfterBattle: | |||
| case this.CharacterType.RecoverAfterBattle: | |||
| pSkill = new RecoverAfterBattle(); | |||
| break; | |||
| case CharacterType.SpeedUpWhenLeavingGrass: | |||
| case this.CharacterType.SpeedUpWhenLeavingGrass: | |||
| pSkill = new SpeedUpWhenLeavingGrass(); | |||
| break; | |||
| case CharacterType.Vampire: | |||
| case this.CharacterType.Vampire: | |||
| pSkill = new Vampire(); | |||
| break; | |||
| default: | |||
| @@ -83,7 +86,7 @@ namespace GameClass.GameObj | |||
| switch (commonSkillType) | |||
| { | |||
| case ActiveSkillType.BecomeAssassin: | |||
| cSkill = new BecomeAssassin(); | |||
| cSkill = new BecomeInvisible(); | |||
| break; | |||
| case ActiveSkillType.BecomeVampire: | |||
| cSkill = new BecomeVampire(); | |||
| @@ -102,7 +105,6 @@ namespace GameClass.GameObj | |||
| this.hp = cSkill.MaxHp; | |||
| this.OrgMoveSpeed = cSkill.MoveSpeed; | |||
| this.moveSpeed = cSkill.MoveSpeed; | |||
| this.cd = cSkill.CD; | |||
| this.maxBulletNum = cSkill.MaxBulletNum; | |||
| this.bulletNum = maxBulletNum; | |||
| this.bulletOfPlayer = pSkill.InitBullet; | |||
| @@ -2,6 +2,7 @@ | |||
| using Preparation.Utility; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Numerics; | |||
| using System.Runtime.InteropServices; | |||
| using System.Threading; | |||
| @@ -13,26 +14,7 @@ namespace GameClass.GameObj | |||
| #region 角色的基本属性及方法,包括与道具的交互方法 | |||
| /// <summary> | |||
| /// 装弹冷却 | |||
| /// </summary> | |||
| 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 fixSpeed; | |||
| protected int fixSpeed = 1; | |||
| /// <summary> | |||
| /// 修理电机速度 | |||
| /// </summary> | |||
| @@ -90,7 +72,7 @@ namespace GameClass.GameObj | |||
| get => score; | |||
| } | |||
| public double AttackRange => BulletFactory.BulletAttackRange(this.BulletOfPlayer); | |||
| // public double AttackRange => BulletFactory.BulletAttackRange(this.BulletOfPlayer); | |||
| private double vampire = 0; // 回血率:0-1之间 | |||
| public double Vampire | |||
| @@ -272,16 +254,13 @@ namespace GameClass.GameObj | |||
| /// </summary> | |||
| /// <param name="sub">减血量</param> | |||
| /// <returns>减操作是否成功</returns> | |||
| public bool TrySubHp(int sub) | |||
| public int TrySubHp(int sub) | |||
| { | |||
| if (hp > 0) | |||
| { | |||
| int previousHp = hp; | |||
| lock (gameObjLock) | |||
| hp = 0 >= hp - sub ? 0 : hp - sub; | |||
| hp = hp >= sub ? 0 : hp - sub; | |||
| Debugger.Output(this, " hp has subed to: " + hp.ToString()); | |||
| return true; | |||
| } | |||
| return false; | |||
| return previousHp - hp; | |||
| } | |||
| /* /// <summary> | |||
| /// 增加死亡次数 | |||
| @@ -327,7 +306,7 @@ namespace GameClass.GameObj | |||
| /// <param name="hasSpear"></param> | |||
| /// <param name="attacker">伤害来源</param> | |||
| /// <returns>人物在受到攻击后死了吗</returns> | |||
| public bool BeAttack(Bullet bullet) | |||
| public bool BeAttacked(Bullet bullet) | |||
| { | |||
| lock (beAttackedLock) | |||
| @@ -346,7 +325,7 @@ namespace GameClass.GameObj | |||
| } | |||
| else | |||
| { | |||
| TrySubHp(bullet.AP); | |||
| bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * TrySubHp(bullet.AP))); | |||
| } | |||
| #if DEBUG | |||
| Console.WriteLine($"PlayerID:{ID} is being shot! Now his hp is {hp}."); | |||
| @@ -171,6 +171,7 @@ namespace GameClass.GameObj | |||
| /// </summary> | |||
| /// <returns> 依具体类及该方法参数而定,默认为false </returns> | |||
| protected virtual bool IgnoreCollideExecutor(IGameObj targetObj) => false; | |||
| bool IMoveable.IgnoreCollide(IGameObj targetObj) => IgnoreCollideExecutor(targetObj); | |||
| public GameObj(XY initPos, int initRadius, PlaceType initPlace, GameObjType initType) | |||
| { | |||
| @@ -1,7 +1,4 @@ | |||
| using Preparation.Utility; | |||
| using Preparation.GameData; | |||
| namespace GameClass.GameObj | |||
| namespace GameClass.GameObj | |||
| { | |||
| public static class MapInfo | |||
| { | |||
| @@ -33,6 +33,8 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| ///// <summary> | |||
| ///// 坑人地雷 | |||
| ///// </summary> | |||
| @@ -7,7 +7,7 @@ using Timothy.FrameRateTask; | |||
| namespace GameClass.Skill | |||
| { | |||
| public class BecomeVampire : ICommonSkill // 化身吸血鬼 | |||
| public class BecomeVampire : IActiveSkill // 化身吸血鬼 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed; | |||
| public int MoveSpeed => moveSpeed; | |||
| @@ -15,22 +15,16 @@ namespace GameClass.Skill | |||
| private const int maxHp = (int)(GameData.basicHp / 6 * 9.5); | |||
| public int MaxHp => maxHp; | |||
| private const int cd = GameData.basicCD; | |||
| public int CD => cd; | |||
| private const int maxBulletNum = GameData.basicBulletNum * 2 / 3; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD / 3 * 4; | |||
| public int DurationTime => GameData.commonSkillTime; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object CommonSkillLock => commonSkillLock; | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| public bool SkillEffect(Character player) | |||
| { | |||
| return CommonSkillFactory.SkillEffect(this, player, () => | |||
| return ActiveSkillFactory.SkillEffect(this, player, () => | |||
| { | |||
| player.Vampire += 0.5; | |||
| Debugger.Output(player, "becomes vampire!"); | |||
| @@ -42,28 +36,16 @@ namespace GameClass.Skill | |||
| }); | |||
| } | |||
| } | |||
| public class BecomeAssassin : ICommonSkill // 化身刺客,隐身 | |||
| public class BecomeInvisible : IActiveSkill | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed / 3 * 5; | |||
| public int MoveSpeed => moveSpeed; | |||
| private const int maxHp = (int)(GameData.basicHp / 6 * 7.5); | |||
| public int MaxHp => maxHp; | |||
| private const int cd = GameData.basicCD; | |||
| public int CD => cd; | |||
| private const int maxBulletNum = GameData.basicBulletNum; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD; | |||
| public int DurationTime => GameData.commonSkillTime / 10 * 6; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object CommonSkillLock => commonSkillLock; | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| public bool SkillEffect(Character player) | |||
| { | |||
| return CommonSkillFactory.SkillEffect(this, player, () => | |||
| return ActiveSkillFactory.SkillEffect(this, player, () => | |||
| { | |||
| player.IsInvisible = true; | |||
| Debugger.Output(player, "uses atombomb!"); | |||
| @@ -72,7 +54,7 @@ namespace GameClass.Skill | |||
| { player.IsInvisible = false; }); | |||
| } | |||
| } | |||
| public class NuclearWeapon : ICommonSkill // 核武器 | |||
| public class NuclearWeapon : IActiveSkill // 核武器 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed / 3 * 4; | |||
| public int MoveSpeed => moveSpeed; | |||
| @@ -80,19 +62,16 @@ namespace GameClass.Skill | |||
| private const int maxHp = GameData.basicHp; | |||
| public int MaxHp => maxHp; | |||
| private const int cd = GameData.basicCD; | |||
| public int CD => cd; | |||
| private const int maxBulletNum = GameData.basicBulletNum * 2 / 3; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD / 3 * 7; | |||
| public int DurationTime => GameData.commonSkillTime / 10; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object CommonSkillLock => commonSkillLock; | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| public bool SkillEffect(Character player) | |||
| { | |||
| return CommonSkillFactory.SkillEffect(this, player, () => | |||
| return ActiveSkillFactory.SkillEffect(this, player, () => | |||
| { | |||
| player.BulletOfPlayer = BulletType.AtomBomb; | |||
| Debugger.Output(player, "uses atombomb!"); | |||
| @@ -101,7 +80,7 @@ namespace GameClass.Skill | |||
| { player.BulletOfPlayer = player.OriBulletOfPlayer; }); | |||
| } | |||
| } | |||
| public class SuperFast : ICommonSkill // 3倍速 | |||
| public class SuperFast : IActiveSkill // 3倍速 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed * 4 / 3; | |||
| public int MoveSpeed => moveSpeed; | |||
| @@ -109,19 +88,16 @@ namespace GameClass.Skill | |||
| private const int maxHp = GameData.basicHp / 6 * 4; | |||
| public int MaxHp => maxHp; | |||
| private const int cd = GameData.basicCD; | |||
| public int CD => cd; | |||
| private const int maxBulletNum = GameData.basicBulletNum * 4 / 3; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD; | |||
| public int DurationTime => GameData.commonSkillTime / 10 * 4; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object CommonSkillLock => commonSkillLock; | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| public bool SkillEffect(Character player) | |||
| { | |||
| return CommonSkillFactory.SkillEffect(this, player, () => | |||
| return ActiveSkillFactory.SkillEffect(this, player, () => | |||
| { | |||
| player.AddMoveSpeed(this.DurationTime, 3.0); | |||
| Debugger.Output(player, "moves very fast!"); | |||
| @@ -130,7 +106,7 @@ namespace GameClass.Skill | |||
| { }); | |||
| } | |||
| } | |||
| public class NoCommonSkill : ICommonSkill // 这种情况不该发生,定义着以防意外 | |||
| public class NoCommonSkill : IActiveSkill // 这种情况不该发生,定义着以防意外 | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed; | |||
| public int MoveSpeed => moveSpeed; | |||
| @@ -138,31 +114,28 @@ namespace GameClass.Skill | |||
| private const int maxHp = GameData.basicHp; | |||
| public int MaxHp => maxHp; | |||
| private const int cd = GameData.basicCD; | |||
| public int CD => cd; | |||
| private const int maxBulletNum = GameData.basicBulletNum; | |||
| public int MaxBulletNum => maxBulletNum; | |||
| // 以上参数以后再改 | |||
| public int SkillCD => GameData.commonSkillCD; | |||
| public int DurationTime => GameData.commonSkillTime; | |||
| private readonly object commonSkillLock = new object(); | |||
| public object CommonSkillLock => commonSkillLock; | |||
| public object ActiveSkillLock => commonSkillLock; | |||
| public bool SkillEffect(Character player) | |||
| { | |||
| return false; | |||
| } | |||
| } | |||
| public static class CommonSkillFactory | |||
| public static class ActiveSkillFactory | |||
| { | |||
| public static bool SkillEffect(ICommonSkill commonSkill, Character player, Action startSkill, Action endSkill) | |||
| public static bool SkillEffect(IActiveSkill activeSkill, Character player, Action startSkill, Action endSkill) | |||
| { | |||
| lock (commonSkill.CommonSkillLock) | |||
| lock (activeSkill.ActiveSkillLock) | |||
| { | |||
| if (player.TimeUntilCommonSkillAvailable == 0) | |||
| { | |||
| player.TimeUntilCommonSkillAvailable = commonSkill.SkillCD; | |||
| player.TimeUntilCommonSkillAvailable = activeSkill.SkillCD; | |||
| new Thread | |||
| (() => | |||
| { | |||
| @@ -175,7 +148,7 @@ namespace GameClass.Skill | |||
| }, | |||
| timeInterval: GameData.frameDuration, | |||
| () => 0, | |||
| maxTotalDuration: (long)(commonSkill.DurationTime) | |||
| maxTotalDuration: (long)(activeSkill.DurationTime) | |||
| ) | |||
| { | |||
| AllowTimeExceed = true, | |||
| @@ -194,7 +167,7 @@ namespace GameClass.Skill | |||
| }, | |||
| timeInterval: GameData.frameDuration, | |||
| () => 0, | |||
| maxTotalDuration: (long)(commonSkill.SkillCD - commonSkill.DurationTime) | |||
| maxTotalDuration: (long)(activeSkill.SkillCD - activeSkill.DurationTime) | |||
| ) | |||
| { | |||
| AllowTimeExceed = true, | |||
| @@ -1,23 +1,29 @@ | |||
| using GameClass.GameObj; | |||
| using Preparation.Utility; | |||
| using System.Threading; | |||
| using System.Collections.Generic; | |||
| namespace GameClass.Skill | |||
| { | |||
| public interface IPassiveSkill | |||
| public interface ISkill | |||
| { | |||
| } | |||
| public interface IPassiveSkill: ISkill | |||
| { | |||
| public BulletType InitBullet { get; } | |||
| public void SkillEffect(Character player); | |||
| } | |||
| public interface ICommonSkill | |||
| public interface IActiveSkill : ISkill | |||
| { | |||
| public int SkillCD { get; } | |||
| public int DurationTime { get; } //技能持续时间 | |||
| public object ActiveSkillLock { get; } | |||
| public bool SkillEffect(Character player); | |||
| } | |||
| public interface ICharacterType | |||
| { | |||
| public int MoveSpeed { get; } | |||
| public int MaxHp { get; } | |||
| public int CD { get; } | |||
| public int MaxBulletNum { get; } | |||
| public bool SkillEffect(Character player); | |||
| public int DurationTime { get; } // 技能持续时间 | |||
| public int SkillCD { get; } | |||
| public object CommonSkillLock { get; } | |||
| public BulletType InitBullet { get; } | |||
| public List<IActiveSkill> ListOfIActiveSkill { get; } | |||
| public List<IPassiveSkill> ListOfIPassiveSkill { get; } | |||
| } | |||
| } | |||
| @@ -0,0 +1,32 @@ | |||
| using GameClass.GameObj; | |||
| using System.Threading; | |||
| using Preparation.Interface; | |||
| using Preparation.Utility; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| namespace GameClass.Skill | |||
| { | |||
| public abstract class Occupation | |||
| { | |||
| public abstract int MoveSpeed { get; } | |||
| public abstract int MaxHp { get; } | |||
| public abstract BulletType InitBullet { get; } | |||
| public abstract List<IActiveSkill> ListOfIActiveSkill { get; } | |||
| public abstract List<IPassiveSkill> ListOfIPassiveSkill { get; } | |||
| } | |||
| public class Assassin : Occupation | |||
| { | |||
| private const int moveSpeed = GameData.basicMoveSpeed/380*473; | |||
| public override int MoveSpeed => moveSpeed; | |||
| private const int maxHp = GameData.basicHp; | |||
| public override int MaxHp => maxHp; | |||
| public override BulletType InitBullet => BulletType.CommonAttackOfGhost; | |||
| public override List<IActiveSkill> ListOfIActiveSkill => new(new IActiveSkill[]{new BecomeInvisible(),}); | |||
| public override List<IPassiveSkill> ListOfIPassiveSkill => new(new IPassiveSkill[] {}); | |||
| } | |||
| } | |||
| @@ -30,7 +30,7 @@ namespace Gaming | |||
| { | |||
| foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator]) | |||
| { | |||
| if (GameData.IsInTheSameCell(generator.Position, player.Position)) | |||
| if (GameData.ApproachToInteract(generator.Position, player.Position)) | |||
| { | |||
| generatorForFix = generator; | |||
| break; | |||
| @@ -4,6 +4,7 @@ using System.Collections.Generic; | |||
| using GameClass.GameObj; | |||
| using Preparation.Utility; | |||
| using GameEngine; | |||
| using Preparation.Interface; | |||
| namespace Gaming | |||
| { | |||
| @@ -34,67 +35,80 @@ namespace Gaming | |||
| } | |||
| ); | |||
| } | |||
| private void BombOnePlayer(Bullet bullet, Character playerBeingShot) | |||
| private bool CanBeBombed(Bullet bullet, GameObjType gameObjType) | |||
| { | |||
| if (playerBeingShot.BeAttack(bullet)) | |||
| if (gameObjType==GameObjType.Character)return true; | |||
| return false; | |||
| } | |||
| private void BombObj(Bullet bullet, GameObj objBeingShot) | |||
| { | |||
| switch (objBeingShot.Type) | |||
| { | |||
| playerBeingShot.CanMove = false; | |||
| playerBeingShot.IsResetting = true; | |||
| // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| // try | |||
| //{ | |||
| // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot); | |||
| // } | |||
| // finally | |||
| //{ | |||
| // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); | |||
| // } | |||
| Prop? dropProp = null; | |||
| if (playerBeingShot.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 | |||
| { | |||
| dropProp = playerBeingShot.PropInventory; | |||
| dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell)); | |||
| } | |||
| gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock(); | |||
| try | |||
| { | |||
| if (dropProp != null) | |||
| gameMap.GameObjDict[GameObjType.Prop].Add(dropProp); | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock(); | |||
| } | |||
| playerBeingShot.Reset(); | |||
| ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 | |||
| new Thread | |||
| (() => | |||
| case GameObjType.Character: | |||
| Character playerBeingShot= (Character)objBeingShot; | |||
| if (playerBeingShot.BeAttacked(bullet)) | |||
| { | |||
| Thread.Sleep(GameData.reviveTime); | |||
| playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾 | |||
| playerBeingShot.CanMove = false; | |||
| playerBeingShot.IsResetting = true; | |||
| // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| // try | |||
| //{ | |||
| // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot); | |||
| // gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot); | |||
| // } | |||
| // finally | |||
| //{ | |||
| // gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); | |||
| // } | |||
| // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); } | |||
| if (gameMap.Timer.IsGaming) | |||
| Prop? dropProp = null; | |||
| if (playerBeingShot.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地 | |||
| { | |||
| dropProp = playerBeingShot.PropInventory; | |||
| dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell)); | |||
| } | |||
| gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock(); | |||
| try | |||
| { | |||
| playerBeingShot.CanMove = true; | |||
| if (dropProp != null) | |||
| gameMap.GameObjDict[GameObjType.Prop].Add(dropProp); | |||
| } | |||
| playerBeingShot.IsResetting = false; | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock(); | |||
| } | |||
| playerBeingShot.Reset(); | |||
| ((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分 | |||
| /* new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(GameData.reviveTime); | |||
| playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾 | |||
| // gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock(); | |||
| // try | |||
| //{ | |||
| // gameMap.GameObjDict[GameObjType.Character].Add(playerBeingShot); | |||
| // } | |||
| // finally { gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock(); } | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| playerBeingShot.CanMove = true; | |||
| } | |||
| playerBeingShot.IsResetting = false; | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| */ | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| break; | |||
| } | |||
| } | |||
| private void BulletBomb(Bullet bullet, GameObj? objBeingShot) | |||
| { | |||
| #if DEBUG | |||
| @@ -127,6 +141,55 @@ namespace Gaming | |||
| gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock(); | |||
| } | |||
| if (!bullet.IsToBomb) | |||
| { | |||
| if (objBeingShot==null) | |||
| { | |||
| if (bullet.Backswing>0) | |||
| { | |||
| bullet.Parent.CanMove=false; | |||
| bullet.Parent.IsMoving=false; | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(bullet.Backswing); | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| return; | |||
| } | |||
| BombObj(bullet, objBeingShot); | |||
| if (bullet.RecoveryFromHit>0) | |||
| { | |||
| bullet.Parent.CanMove=false; | |||
| bullet.Parent.IsMoving=false; | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(bullet.RecoveryFromHit); | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| return; | |||
| } | |||
| /*if (objBeingShot != null) | |||
| { | |||
| else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。 | |||
| @@ -136,31 +199,79 @@ namespace Gaming | |||
| }*/ | |||
| // 子弹爆炸会发生的事↓↓↓ | |||
| var beAttackedList = new List<Character>(); | |||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | |||
| try | |||
| var beAttackedList = new List<IGameObj>(); | |||
| foreach (var kvp in gameMap.GameObjDict) | |||
| { | |||
| foreach (Character player in gameMap.GameObjDict[GameObjType.Character]) | |||
| if (CanBeBombed(bullet, kvp.Key)) | |||
| { | |||
| if (bullet.CanAttack(player)) | |||
| gameMap.GameObjLockDict[kvp.Key].EnterWriteLock(); | |||
| try | |||
| { | |||
| beAttackedList.Add(player); | |||
| if (player.ID != bullet.Parent.ID) | |||
| bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * bullet.AP)); | |||
| foreach (var item in gameMap.GameObjDict[kvp.Key]) | |||
| if (bullet.CanAttack((GameObj)item)) | |||
| { | |||
| beAttackedList.Add(item); | |||
| } | |||
| } | |||
| finally | |||
| { | |||
| gameMap.GameObjLockDict[kvp.Key].ExitWriteLock(); | |||
| } | |||
| } | |||
| } | |||
| finally | |||
| foreach (GameObj beAttackedObj in beAttackedList) | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock(); | |||
| BombObj(bullet, beAttackedObj); | |||
| } | |||
| foreach (Character beAttackedPlayer in beAttackedList) | |||
| if (objBeingShot==null) | |||
| { | |||
| BombOnePlayer(bullet, beAttackedPlayer); | |||
| if (bullet.Backswing>0) | |||
| { | |||
| bullet.Parent.CanMove=false; | |||
| bullet.Parent.IsMoving=false; | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(bullet.Backswing); | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| } | |||
| else | |||
| { | |||
| if (bullet.RecoveryFromHit>0) | |||
| { | |||
| bullet.Parent.CanMove=false; | |||
| bullet.Parent.IsMoving=false; | |||
| new Thread | |||
| (() => | |||
| { | |||
| Thread.Sleep(bullet.RecoveryFromHit); | |||
| if (gameMap.Timer.IsGaming) | |||
| { | |||
| bullet.Parent.CanMove = true; | |||
| } | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| } | |||
| } | |||
| beAttackedList.Clear(); | |||
| } | |||
| public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头) | |||
| { // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | |||
| if (player == null) | |||
| @@ -192,7 +303,7 @@ namespace Gaming | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock(); | |||
| } | |||
| moveEngine.MoveObj(bullet, (int)((player.AttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| moveEngine.MoveObj(bullet, (int)((bullet.BulletAttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| #if DEBUG | |||
| Console.WriteLine($"playerID:{player.ID} successfully attacked!"); | |||
| #endif | |||
| @@ -31,7 +31,7 @@ namespace Gaming | |||
| public List<Team> TeamList => teamList; | |||
| private readonly Map gameMap; | |||
| public Map GameMap => gameMap; | |||
| private readonly int numOfTeam; | |||
| // private readonly int numOfTeam; | |||
| public long AddPlayer(PlayerInitInfo playerInitInfo) | |||
| { | |||
| if (!Team.teamExists(playerInitInfo.teamID)) | |||
| @@ -57,7 +57,7 @@ namespace Gaming | |||
| newPlayer.TeamID = playerInitInfo.teamID; | |||
| newPlayer.PlayerID = playerInitInfo.playerID; | |||
| new Thread //人物装弹 | |||
| /*new Thread //人物装弹 | |||
| ( | |||
| () => | |||
| { | |||
| @@ -85,16 +85,16 @@ namespace Gaming | |||
| ) | |||
| { | |||
| AllowTimeExceed = true | |||
| /*MaxTolerantTimeExceedCount = 5, | |||
| MaxTolerantTimeExceedCount = 5, | |||
| TimeExceedAction = exceedTooMuch => | |||
| { | |||
| if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!"); | |||
| }*/ | |||
| } | |||
| } | |||
| .Start(); | |||
| } | |||
| ) | |||
| { IsBackground = true }.Start(); | |||
| { IsBackground = true }.Start();*/ | |||
| return newPlayer.ID; | |||
| } | |||
| @@ -132,7 +132,7 @@ namespace Gaming | |||
| if (kvp.Key == GameObjType.Bullet || kvp.Key == GameObjType.Character || kvp.Key == GameObjType.Prop) | |||
| { | |||
| gameMap.GameObjLockDict[kvp.Key].EnterWriteLock(); | |||
| try | |||
| try | |||
| { | |||
| foreach (var item in gameMap.GameObjDict[kvp.Key]) | |||
| { | |||
| @@ -342,7 +342,7 @@ namespace Gaming | |||
| gameMap = new Map(mapResource); | |||
| // 加入队伍 | |||
| this.numOfTeam = numOfTeam; | |||
| // this.numOfTeam = numOfTeam; | |||
| teamList = new List<Team>(); | |||
| for (int i = 0; i < numOfTeam; ++i) | |||
| { | |||
| @@ -42,7 +42,9 @@ namespace Preparation.Utility | |||
| OrdinaryBullet = 1, // 普通子弹 | |||
| AtomBomb = 2, // 原子弹 | |||
| FastBullet = 3, // 快速子弹 | |||
| LineBullet = 4 // 直线子弹 | |||
| LineBullet = 4, // 直线子弹 | |||
| FlyingKnife = 5, //飞刀 | |||
| CommonAttackOfGhost = 6 | |||
| } | |||
| public enum PropType // 道具类型 | |||
| { | |||
| @@ -66,7 +68,7 @@ namespace Preparation.Utility | |||
| public enum ActiveSkillType // 主动技能 | |||
| { | |||
| Null = 0, | |||
| BecomeAssassin = 1, | |||
| BecomeInvisible = 1, | |||
| BecomeVampire = 2, | |||
| NuclearWeapon = 3, | |||
| SuperFast = 4, | |||
| @@ -1,4 +1,5 @@ | |||
| namespace Preparation.Utility | |||
| using System; | |||
| namespace Preparation.Utility | |||
| { | |||
| public static class GameData | |||
| { | |||
| @@ -37,19 +38,25 @@ | |||
| { | |||
| return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2); | |||
| } | |||
| public static bool ApproachToInteract(XY pos1, XY pos2) | |||
| { | |||
| return Math.Abs(PosGridToCellX(pos1) - PosGridToCellX(pos2))<=1 && Math.Abs(PosGridToCellY(pos1) - PosGridToCellY(pos2))<=1; | |||
| } | |||
| #endregion | |||
| #region 角色相关 | |||
| public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径 | |||
| public const int basicAp = 3000; // 初始攻击力 | |||
| public const int basicHp = 6000; // 初始血量 | |||
| public const int basicCD = 3000; // 初始子弹冷却 | |||
| public const int basicApOfGhost = 500; // 初始攻击力 | |||
| public const int basicHp = 1003; // 初始血量 | |||
| public const int basicBackswing = 500;//基本后摇时间 | |||
| public const int basicRecoveryFromHit = 4300;//基本命中攻击恢复时长 | |||
| public const int basicBulletNum = 3; // 基本初始子弹量 | |||
| public const int MinAP = 0; // 最小攻击力 | |||
| public const int MaxAP = int.MaxValue; // 最大攻击力 | |||
| public const double basicAttackRange = 9000; // 基本攻击范围 | |||
| public const double basicRemoteAttackRange = 9000; // 基本远程攻击范围 | |||
| public const double basicAttackShortRange = 2700; // 基本近程攻击范围 | |||
| public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围 | |||
| public const int basicMoveSpeed = 3000; // 基本移动速度,单位:s-1 | |||
| public const int basicBulletMoveSpeed = 3000; // 基本子弹移动速度,单位:s-1 | |||
| public const int basicMoveSpeed = 3800; // 基本移动速度,单位:s-1 | |||
| public const int basicBulletMoveSpeed = 5400; // 基本子弹移动速度,单位:s-1 | |||
| public const int characterMaxSpeed = 12000; // 最大速度 | |||
| public const int addScoreWhenKillOneLevelPlayer = 30; // 击杀一级角色获得的加分 | |||
| public const int commonSkillCD = 30000; // 普通技能标准冷却时间 | |||
| @@ -70,7 +77,7 @@ | |||
| public const long PropProduceTime = 10000; | |||
| public const int PropDuration = 10000; | |||
| public const int degreeOfFixedGenerator = 100; | |||
| public const int degreeOfFixedGenerator = 2000; | |||
| #endregion | |||
| #region 游戏帧相关 | |||
| public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 | |||