From eed264a2f53e4d5c3d05c0da352e2e004fa84351 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Mon, 8 May 2023 14:04:00 +0800 Subject: [PATCH] perf: :zap: use more safe, efficient way to update BulletNum --- .../GameClass/GameObj/Character/Character.cs | 116 +++++++----------- logic/GameClass/GameObj/Moveable.cs | 5 +- logic/Gaming/AttackManager.cs | 3 +- logic/Gaming/CharacterManager .cs | 70 +++++------ logic/Preparation/Interface/ICharacter.cs | 2 +- 5 files changed, 82 insertions(+), 114 deletions(-) diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 270b1ec..2776113 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -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(); /// /// 装弹冷却 @@ -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(); } } } - /// - /// 进行一次攻击 - /// - /// 攻击操作发出的子弹 - 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; - /// - /// 尝试将子弹数量减1 - /// - /// 减操作是否成功 - 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; } } + /// - /// 尝试将子弹数量加1 + /// 进行一次攻击 /// - /// 加操作是否成功 - public bool TryAddBulletNum() + /// 攻击操作发出的子弹 + 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(); } diff --git a/logic/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs index da9b4d6..10351dc 100644 --- a/logic/GameClass/GameObj/Moveable.cs +++ b/logic/GameClass/GameObj/Moveable.cs @@ -141,8 +141,9 @@ namespace GameClass.GameObj moveReaderWriterLock.EnterWriteLock(); try { - lock (moveObjLock) { - moveSpeed=value; + lock (moveObjLock) + { + moveSpeed = value; } } finally diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 6f900b5..360804f 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -123,7 +123,6 @@ namespace Gaming if (bullet.TypeOfBullet == BulletType.BombBomb && objBeingShot != null) { bullet.Parent!.BulletOfPlayer = BulletType.JumpyDumpty; - Debugger.Output(bullet.Parent, bullet.Parent.CharacterType.ToString() + " " + bullet.Parent.BulletNum.ToString()); Attack((Character)bullet.Parent, bullet.FacingDirection.Angle() + Math.PI / 2.0); Attack((Character)bullet.Parent, bullet.FacingDirection.Angle() + Math.PI * 3.0 / 2.0); } @@ -173,7 +172,7 @@ namespace Gaming Debugger.Output(player, player.Position.ToString() + " " + player.Radius.ToString() + " " + BulletFactory.BulletRadius(player.BulletOfPlayer).ToString()); - Bullet? bullet = player.Attack(angle); + Bullet? bullet = player.Attack(angle, gameMap.Timer.nowTime()); if (bullet != null) { diff --git a/logic/Gaming/CharacterManager .cs b/logic/Gaming/CharacterManager .cs index 31a5b18..bb49b8c 100644 --- a/logic/Gaming/CharacterManager .cs +++ b/logic/Gaming/CharacterManager .cs @@ -66,43 +66,39 @@ namespace Gaming newPlayer.TeamID = teamID; newPlayer.PlayerID = playerID; - #region 人物装弹 - new Thread - ( - () => - { - while (!gameMap.Timer.IsGaming) - Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval)); - long lastTime = Environment.TickCount64; - new FrameRateTaskExecutor( - loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, - loopToDo: () => - { - long nowTime = Environment.TickCount64; - if (newPlayer.BulletNum == newPlayer.MaxBulletNum) - lastTime = nowTime; - else if (nowTime - lastTime >= newPlayer.CD) - { - _ = newPlayer.TryAddBulletNum(); - lastTime = nowTime; - } - }, - timeInterval: GameData.checkInterval, - finallyReturn: () => 0 - ) - { - AllowTimeExceed = true/*, - 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(); - #endregion + /* #region 人物装弹 + new Thread + ( + () => + { + while (!gameMap.Timer.IsGaming) + Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval)); + long lastTime = Environment.TickCount64; + new FrameRateTaskExecutor( + loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, + loopToDo: () => + { + long nowTime = Environment.TickCount64; + if (newPlayer.BulletNum == newPlayer.MaxBulletNum) + lastTime = nowTime; + else if (nowTime - lastTime >= newPlayer.CD) + { + _ = newPlayer.TryAddBulletNum(); + lastTime = nowTime; + } + }, + timeInterval: GameData.checkInterval, + finallyReturn: () => 0 + ) + { + AllowTimeExceed = true, + } + .Start(); + } + ) + { IsBackground = true }.Start(); + #endregion + */ #region BGM,牵制得分更新 new Thread ( diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index 29d087f..3af523d 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -13,7 +13,7 @@ namespace Preparation.Interface public PlayerStateType PlayerState { get; } public BulletType BulletOfPlayer { get; set; } public CharacterType CharacterType { get; } - public int BulletNum { get; } + public int UpdateBulletNum(int time); public long ThreadNum { get; } public bool IsGhost();