|
|
|
@@ -10,10 +10,7 @@ namespace GameClass.GameObj |
|
|
|
{ |
|
|
|
#region 装弹、攻击相关的基本属性及方法 |
|
|
|
|
|
|
|
protected readonly object AttackLock = new(); |
|
|
|
private readonly ReaderWriterLockSlim attackReaderWriterLock = new(); |
|
|
|
public ReaderWriterLockSlim AttackReaderWriterLock => attackReaderWriterLock; |
|
|
|
//规定AttackReaderWriterLock>AttackLock |
|
|
|
private readonly object attackLock = new(); |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 装弹冷却 |
|
|
|
@@ -23,114 +20,89 @@ namespace GameClass.GameObj |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
attackReaderWriterLock.EnterReadLock(); |
|
|
|
try |
|
|
|
lock (attackLock) |
|
|
|
{ |
|
|
|
return cd; |
|
|
|
} |
|
|
|
finally { attackReaderWriterLock.ExitReadLock(); } |
|
|
|
} |
|
|
|
} |
|
|
|
public int OrgCD { get; protected set; } |
|
|
|
|
|
|
|
protected int maxBulletNum; |
|
|
|
public int MaxBulletNum |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
attackReaderWriterLock.EnterReadLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
return maxBulletNum; |
|
|
|
} |
|
|
|
finally { attackReaderWriterLock.ExitReadLock(); } |
|
|
|
} |
|
|
|
} |
|
|
|
protected int bulletNum; |
|
|
|
public int BulletNum => bulletNum; // 目前持有的子弹数 |
|
|
|
|
|
|
|
public readonly BulletType OriBulletOfPlayer; |
|
|
|
private BulletType bulletOfPlayer; |
|
|
|
public BulletType BulletOfPlayer |
|
|
|
{ |
|
|
|
get |
|
|
|
{ |
|
|
|
attackReaderWriterLock.EnterReadLock(); |
|
|
|
try |
|
|
|
lock (attackLock) |
|
|
|
{ |
|
|
|
return bulletOfPlayer; |
|
|
|
} |
|
|
|
finally { attackReaderWriterLock.ExitReadLock(); } |
|
|
|
} |
|
|
|
set |
|
|
|
{ |
|
|
|
attackReaderWriterLock.EnterWriteLock(); |
|
|
|
try |
|
|
|
lock (attackLock) |
|
|
|
{ |
|
|
|
lock (AttackLock) |
|
|
|
{ |
|
|
|
bulletOfPlayer = value; |
|
|
|
cd = OrgCD = (BulletFactory.BulletCD(value)); |
|
|
|
Debugger.Output(this, string.Format("'s CD has been set to: {0}.", cd)); |
|
|
|
maxBulletNum = bulletNum = (BulletFactory.BulletNum(value)); |
|
|
|
} |
|
|
|
bulletOfPlayer = value; |
|
|
|
cd = OrgCD = (BulletFactory.BulletCD(value)); |
|
|
|
Debugger.Output(this, string.Format("'s CD has been set to: {0}.", cd)); |
|
|
|
maxBulletNum = bulletNum = (BulletFactory.BulletNum(value)); |
|
|
|
} |
|
|
|
finally { attackReaderWriterLock.ExitWriteLock(); } |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 进行一次攻击 |
|
|
|
/// </summary> |
|
|
|
/// <returns>攻击操作发出的子弹</returns> |
|
|
|
public Bullet? Attack(double angle) |
|
|
|
protected int maxBulletNum; |
|
|
|
public int MaxBulletNum |
|
|
|
{ |
|
|
|
if (TrySubBulletNum()) |
|
|
|
get |
|
|
|
{ |
|
|
|
XY res = Position + new XY // 子弹紧贴人物生成。 |
|
|
|
( |
|
|
|
(int)(Math.Abs((Radius + BulletFactory.BulletRadius(BulletOfPlayer)) * Math.Cos(angle))) * ((Math.Cos(angle) > 0) ? 1 : -1), |
|
|
|
(int)(Math.Abs((Radius + BulletFactory.BulletRadius(BulletOfPlayer)) * Math.Sin(angle))) * ((Math.Sin(angle) > 0) ? 1 : -1) |
|
|
|
); |
|
|
|
Bullet? bullet = BulletFactory.GetBullet(this, res); |
|
|
|
if (bullet == null) return null; |
|
|
|
facingDirection = new(angle, bullet.BulletAttackRange); |
|
|
|
return bullet; |
|
|
|
lock (attackLock) |
|
|
|
{ |
|
|
|
return maxBulletNum; |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
return null; |
|
|
|
} |
|
|
|
private int bulletNum; |
|
|
|
private int updateTimeOfBulletNum = 0; |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 尝试将子弹数量减1 |
|
|
|
/// </summary> |
|
|
|
/// <returns>减操作是否成功</returns> |
|
|
|
private bool TrySubBulletNum() |
|
|
|
public int UpdateBulletNum(int time) |
|
|
|
{ |
|
|
|
lock (gameObjLock) |
|
|
|
lock (attackLock) |
|
|
|
{ |
|
|
|
if (bulletNum > 0) |
|
|
|
if (bulletNum < maxBulletNum) |
|
|
|
{ |
|
|
|
--bulletNum; |
|
|
|
return true; |
|
|
|
int add = Math.Min(maxBulletNum - bulletNum, (time - updateTimeOfBulletNum) / cd); |
|
|
|
updateTimeOfBulletNum += add * cd; |
|
|
|
return (bulletNum += add); |
|
|
|
} |
|
|
|
return false; |
|
|
|
return maxBulletNum; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary> |
|
|
|
/// 尝试将子弹数量加1 |
|
|
|
/// 进行一次攻击 |
|
|
|
/// </summary> |
|
|
|
/// <returns>加操作是否成功</returns> |
|
|
|
public bool TryAddBulletNum() |
|
|
|
/// <returns>攻击操作发出的子弹</returns> |
|
|
|
public Bullet? Attack(double angle, int time) |
|
|
|
{ |
|
|
|
lock (gameObjLock) |
|
|
|
lock (attackLock) |
|
|
|
{ |
|
|
|
if (bulletNum < maxBulletNum) |
|
|
|
if (UpdateBulletNum(time) > 0) |
|
|
|
{ |
|
|
|
++bulletNum; |
|
|
|
return true; |
|
|
|
if(bulletNum==maxBulletNum)updateTimeOfBulletNum = time; |
|
|
|
--bulletNum; |
|
|
|
XY res = Position + new XY // 子弹紧贴人物生成。 |
|
|
|
( |
|
|
|
(int)(Math.Abs((Radius + BulletFactory.BulletRadius(BulletOfPlayer)) * Math.Cos(angle))) * ((Math.Cos(angle) > 0) ? 1 : -1), |
|
|
|
(int)(Math.Abs((Radius + BulletFactory.BulletRadius(BulletOfPlayer)) * Math.Sin(angle))) * ((Math.Sin(angle) > 0) ? 1 : -1) |
|
|
|
); |
|
|
|
Bullet? bullet = BulletFactory.GetBullet(this, res); |
|
|
|
if (bullet == null) return null; |
|
|
|
facingDirection = new(angle, bullet.BulletAttackRange); |
|
|
|
return bullet; |
|
|
|
} |
|
|
|
return false; |
|
|
|
else |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@@ -405,7 +377,7 @@ namespace GameClass.GameObj |
|
|
|
position = GameData.PosWhoDie; |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
finally |
|
|
|
{ |
|
|
|
MoveReaderWriterLock.ExitWriteLock(); |
|
|
|
} |
|
|
|
|