Browse Source

build:

-
tags/0.1.0
shangfengh 2 years ago
parent
commit
f9d936b8cb
17 changed files with 462 additions and 305 deletions
  1. +0
    -0
      logic/GameClass/GameObj/Bullet/BombedBullet.cs
  2. +62
    -113
      logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs
  3. +7
    -0
      logic/GameClass/GameObj/Bullet/Bullet.Student.cs
  4. +89
    -0
      logic/GameClass/GameObj/Bullet/Bullet.cs
  5. +23
    -21
      logic/GameClass/GameObj/Character/Character.SkillManager.cs
  6. +9
    -30
      logic/GameClass/GameObj/Character/Character.cs
  7. +1
    -0
      logic/GameClass/GameObj/GameObj.cs
  8. +1
    -4
      logic/GameClass/GameObj/Map/MapInfo.cs
  9. +2
    -0
      logic/GameClass/GameObj/Prop.cs
  10. +20
    -47
      logic/GameClass/Skill/ActiveSkill.cs
  11. +16
    -10
      logic/GameClass/Skill/ISkill.cs
  12. +32
    -0
      logic/GameClass/Skill/Occupation.cs
  13. +1
    -1
      logic/Gaming/ActionManager.cs
  14. +173
    -62
      logic/Gaming/AttackManager.cs
  15. +7
    -7
      logic/Gaming/Game.cs
  16. +4
    -2
      logic/Preparation/Utility/EnumType.cs
  17. +15
    -8
      logic/Preparation/Utility/GameData.cs

logic/GameClass/GameObj/BombedBullet.cs → logic/GameClass/GameObj/Bullet/BombedBullet.cs View File


logic/GameClass/GameObj/Bullet.cs → logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs View File

@@ -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;
}
}
}
}

+ 7
- 0
logic/GameClass/GameObj/Bullet/Bullet.Student.cs View File

@@ -0,0 +1,7 @@
using Preparation.Interface;
using Preparation.Utility;
using System;

namespace GameClass.GameObj
{
}

+ 89
- 0
logic/GameClass/GameObj/Bullet/Bullet.cs View File

@@ -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;
}
}
}
}

+ 23
- 21
logic/GameClass/GameObj/Character/Character.SkillManager.cs View File

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


+ 9
- 30
logic/GameClass/GameObj/Character/Character.cs View File

@@ -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}.");


+ 1
- 0
logic/GameClass/GameObj/GameObj.cs View File

@@ -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
- 4
logic/GameClass/GameObj/Map/MapInfo.cs View File

@@ -1,7 +1,4 @@
using Preparation.Utility;
using Preparation.GameData;

namespace GameClass.GameObj
namespace GameClass.GameObj
{
public static class MapInfo
{


+ 2
- 0
logic/GameClass/GameObj/Prop.cs View File

@@ -33,6 +33,8 @@ namespace GameClass.GameObj
}
}



///// <summary>
///// 坑人地雷
///// </summary>


logic/GameClass/Skill/CommonSkill.cs → logic/GameClass/Skill/ActiveSkill.cs View File

@@ -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,

+ 16
- 10
logic/GameClass/Skill/ISkill.cs View File

@@ -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; }
}
}

+ 32
- 0
logic/GameClass/Skill/Occupation.cs View File

@@ -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[] {});
}

}

+ 1
- 1
logic/Gaming/ActionManager.cs View File

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


+ 173
- 62
logic/Gaming/AttackManager.cs View File

@@ -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


+ 7
- 7
logic/Gaming/Game.cs View File

@@ -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)
{


+ 4
- 2
logic/Preparation/Utility/EnumType.cs View File

@@ -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,


+ 15
- 8
logic/Preparation/Utility/GameData.cs View File

@@ -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; // 检查位置标志、补充子弹的帧时长


Loading…
Cancel
Save