From c9593643a3965f5b5bbc6fd736019b007ca0e5c8 Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Wed, 26 Apr 2023 00:17:20 +0800 Subject: [PATCH] fix: :bug: fix the bug about attacking When clipping --- docs/CAPI接口(python).md | 3 +- docs/QandA.md | 2 +- .../GameClass/GameObj/Character/Character.cs | 2 +- logic/GameEngine/MoveEngine.cs | 188 ++++++++++-------- logic/Gaming/ActionManager.cs | 1 + logic/Gaming/AttackManager.cs | 3 +- 6 files changed, 114 insertions(+), 85 deletions(-) diff --git a/docs/CAPI接口(python).md b/docs/CAPI接口(python).md index da5fc05..1b36a28 100644 --- a/docs/CAPI接口(python).md +++ b/docs/CAPI接口(python).md @@ -8,7 +8,8 @@ #### 移动 -- `def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]`:移动,`timeInMilliseconds` 为移动时间,单位毫秒;`angleInRadian` 表示移动方向,单位弧度,使用极坐标,**竖直向下方向为 x 轴,水平向右方向为 y 轴**因为移动过程中你会受到多种干扰使得移动结果不符合你的预期;因此建议小步移动,边移动边考虑之后的行为。 +- `def Move(self, timeInMilliseconds: int, angle: float) -> Future[bool]`:移动,`timeInMilliseconds` 为移动时间,单位毫秒;`angleInRadian` 表示移动方向,单位弧度,使用极坐标,**竖直向下方向为 x 轴,水平向右方向为 y 轴**因为移动过程中你会受到多种干扰使得移动结果不符合你的预期;因此建议小步移动,边移动边考虑之后的行为。 + - 5ms以内的移动指令会被禁止,你不应当使用过小的移动指令 - `def MoveRight(self, timeInMilliseconds: int) -> Future[bool]`即向右移动,`MoveLeft`、`MoveDown`、`MoveUp`同理 #### 使用技能 diff --git a/docs/QandA.md b/docs/QandA.md index 9483d9a..1ccc5c8 100644 --- a/docs/QandA.md +++ b/docs/QandA.md @@ -73,4 +73,4 @@ A:初赛结束会调数值及机制,增加新角色 Q:初赛后会修改什么呢? -A:技能冷却时间等属性设为不可见;出生点随机性或可选性;增强教师等职业,削弱职业 \ No newline at end of file +A:技能冷却时间等属性设为不可见;出生点随机性或可选性;增强教师等职业,削弱职业;规范Debug信息 \ No newline at end of file diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 2231030..c6c0624 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -594,7 +594,7 @@ namespace GameClass.GameObj { return true; } - if (targetObj.Type == GameObjType.Character && XY.DistanceFloor3(targetObj.Position, this.Position) < this.Radius + targetObj.Radius - GameData.adjustLength) + if (targetObj.Type == GameObjType.Character && XY.DistanceCeil3(targetObj.Position, this.Position) < this.Radius + targetObj.Radius - GameData.adjustLength) return true; return false; } diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs index d0a44b2..443d989 100644 --- a/logic/GameEngine/MoveEngine.cs +++ b/logic/GameEngine/MoveEngine.cs @@ -91,106 +91,132 @@ namespace GameEngine double deltaLen = moveVecLength - Math.Sqrt(obj.MovingSetPos(res, GetPlaceType(obj.Position + res))); // 转向,并用deltaLen存储行走的误差 IGameObj? collisionObj = null; bool isDestroyed = false; - new FrameRateTaskExecutor( - () => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting && obj.IsMoving, - () => + + bool flag; // 循环标志 + do + { + flag = false; + collisionObj = collisionChecker.CheckCollision(obj, obj.Position); + if (collisionObj == null) + break; + + switch (OnCollision(obj, collisionObj, res)) { - moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond; - res = new XY(direction, moveVecLength); + case AfterCollision.ContinueCheck: + flag = true; + break; + case AfterCollision.Destroyed: + Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); + isDestroyed = true; + break; + case AfterCollision.MoveMax: + break; + } + } while (flag); - // 越界情况处理:如果越界,则与越界方块碰撞 - bool flag; // 循环标志 - do + if (!isDestroyed) + { + new FrameRateTaskExecutor( + () => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting && obj.IsMoving, + () => { - flag = false; - collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res); - if (collisionObj == null) - break; + moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond; + res = new XY(direction, moveVecLength); - switch (OnCollision(obj, collisionObj, res)) + // 越界情况处理:如果越界,则与越界方块碰撞 + bool flag; // 循环标志 + do { - case AfterCollision.ContinueCheck: - flag = true; - break; - case AfterCollision.Destroyed: - Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); - isDestroyed = true; - return false; - case AfterCollision.MoveMax: - MoveMax(obj, res); - moveVecLength = 0; - res = new XY(direction, moveVecLength); + flag = false; + collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res); + if (collisionObj == null) break; - } - } while (flag); - deltaLen += moveVecLength - Math.Sqrt(obj.MovingSetPos(res, GetPlaceType(obj.Position + res))); + switch (OnCollision(obj, collisionObj, res)) + { + case AfterCollision.ContinueCheck: + flag = true; + break; + case AfterCollision.Destroyed: + Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); + isDestroyed = true; + return false; + case AfterCollision.MoveMax: + MoveMax(obj, res); + moveVecLength = 0; + res = new XY(direction, moveVecLength); + break; + } + } while (flag); - return true; - }, - GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond, - () => - { - int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond); - bool flag; - do + deltaLen += moveVecLength - Math.Sqrt(obj.MovingSetPos(res, GetPlaceType(obj.Position + res))); + + return true; + }, + GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond, + () => { - flag = false; - if (!isDestroyed) + int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond); + bool flag; + do { - moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell; - res = new XY(direction, moveVecLength); - if ((collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res)) == null) - { - obj.MovingSetPos(res, GetPlaceType(obj.Position + res)); - } - else + flag = false; + if (!isDestroyed) { - switch (OnCollision(obj, collisionObj, res)) + moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell; + res = new XY(direction, moveVecLength); + if ((collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res)) == null) + { + obj.MovingSetPos(res, GetPlaceType(obj.Position + res)); + } + else { - case AfterCollision.ContinueCheck: - flag = true; - break; - case AfterCollision.Destroyed: - Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); - isDestroyed = true; - break; - case AfterCollision.MoveMax: - MoveMax(obj, res); - moveVecLength = 0; - res = new XY(direction, moveVecLength); - break; + switch (OnCollision(obj, collisionObj, res)) + { + case AfterCollision.ContinueCheck: + flag = true; + break; + case AfterCollision.Destroyed: + Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); + isDestroyed = true; + break; + case AfterCollision.MoveMax: + MoveMax(obj, res); + moveVecLength = 0; + res = new XY(direction, moveVecLength); + break; + } } } + } while (flag); + if (leftTime > 0 && obj.IsMoving) + { + Thread.Sleep(leftTime); // 多移动的在这里补回来 } - } while (flag); - if (leftTime > 0 && obj.IsMoving) - { - Thread.Sleep(leftTime); // 多移动的在这里补回来 - } - lock (obj.MoveLock) - obj.IsMoving = false; // 结束移动 - EndMove(obj); - return 0; - }, - maxTotalDuration: moveTime - ) - { - AllowTimeExceed = true, - MaxTolerantTimeExceedCount = ulong.MaxValue, - TimeExceedAction = b => + lock (obj.MoveLock) + obj.IsMoving = false; // 结束移动 + EndMove(obj); + return 0; + }, + maxTotalDuration: moveTime + ) { - if (b) - Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!"); + AllowTimeExceed = true, + MaxTolerantTimeExceedCount = ulong.MaxValue, + TimeExceedAction = b => + { + if (b) + Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!"); #if DEBUG - else - { - Console.WriteLine("Debug info: Object moving time exceed for once."); - } + else + { + Console.WriteLine("Debug info: Object moving time exceed for once."); + } #endif - } - }.Start(); + } + }.Start(); + } } ).Start(); } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index b4f88fb..68db0be 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -35,6 +35,7 @@ namespace Gaming } public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection) { + if (moveTimeInMilliseconds < 5) return false; if (!playerToMove.Commandable() || !TryToStop()) return false; characterManager.SetPlayerState(playerToMove, PlayerStateType.Moving); moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 5dca755..96be026 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -172,6 +172,7 @@ namespace Gaming return false; Debugger.Output(player, player.CharacterType.ToString() + "Attack in " + player.BulletOfPlayer.ToString()); + Debugger.Output(player, player.Position.ToString() + " " + player.Radius.ToString() + " " + BulletFactory.BulletRadius(player.BulletOfPlayer).ToString()); XY res = player.Position + new XY // 子弹紧贴人物生成。 ( (int)(Math.Abs((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Cos(angle))) * ((Math.Cos(angle) > 0) ? 1 : -1), @@ -183,7 +184,7 @@ namespace Gaming if (bullet != null) { player.FacingDirection = new(angle, bullet.BulletAttackRange); - Debugger.Output(player, "Attack in " + bullet.ToString()); + Debugger.Output(bullet, "Attack in " + bullet.Position.ToString()); bullet.AP += player.TryAddAp() ? GameData.ApPropAdd : 0; bullet.CanMove = true; gameMap.Add(bullet);