| @@ -56,9 +56,9 @@ namespace GameClass.GameObj | |||||
| public static class BulletFactory | public static class BulletFactory | ||||
| { | { | ||||
| public static Bullet? GetBullet(Character character, XY pos) | |||||
| public static Bullet? GetBullet(Character character, XY pos, BulletType bulletType) | |||||
| { | { | ||||
| switch (character.BulletOfPlayer) | |||||
| switch (bulletType) | |||||
| { | { | ||||
| case BulletType.FlyingKnife: | case BulletType.FlyingKnife: | ||||
| return new FlyingKnife(character, pos); | return new FlyingKnife(character, pos); | ||||
| @@ -95,7 +95,7 @@ namespace GameClass.GameObj | |||||
| (int)(Math.Abs((Radius + BulletFactory.BulletRadius(bulletOfPlayer)) * Math.Cos(angle))) * Math.Sign(Math.Cos(angle)), | (int)(Math.Abs((Radius + BulletFactory.BulletRadius(bulletOfPlayer)) * Math.Cos(angle))) * Math.Sign(Math.Cos(angle)), | ||||
| (int)(Math.Abs((Radius + BulletFactory.BulletRadius(bulletOfPlayer)) * Math.Sin(angle))) * Math.Sign(Math.Sin(angle)) | (int)(Math.Abs((Radius + BulletFactory.BulletRadius(bulletOfPlayer)) * Math.Sin(angle))) * Math.Sign(Math.Sin(angle)) | ||||
| ); | ); | ||||
| Bullet? bullet = BulletFactory.GetBullet(this, res); | |||||
| Bullet? bullet = BulletFactory.GetBullet(this, res, this.bulletOfPlayer); | |||||
| if (bullet == null) return null; | if (bullet == null) return null; | ||||
| bullet.AP += TryAddAp() ? GameData.ApPropAdd : 0; | bullet.AP += TryAddAp() ? GameData.ApPropAdd : 0; | ||||
| facingDirection = new(angle, bullet.AttackDistance); | facingDirection = new(angle, bullet.AttackDistance); | ||||
| @@ -325,20 +325,20 @@ namespace GameClass.GameObj | |||||
| private GameObj? whatInteractingWith = null; | private GameObj? whatInteractingWith = null; | ||||
| public GameObj? WhatInteractingWith => whatInteractingWith; | public GameObj? WhatInteractingWith => whatInteractingWith; | ||||
| public void ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| public long ChangePlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| { | { | ||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| ++stateNum; | |||||
| whatInteractingWith = gameObj; | whatInteractingWith = gameObj; | ||||
| if (value != PlayerStateType.Moving) | if (value != PlayerStateType.Moving) | ||||
| IsMoving = false; | IsMoving = false; | ||||
| playerState = (value == PlayerStateType.Moving) ? PlayerStateType.Null : value; | playerState = (value == PlayerStateType.Moving) ? PlayerStateType.Null : value; | ||||
| //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | ||||
| return ++stateNum; | |||||
| } | } | ||||
| } | } | ||||
| public void ChangePlayerStateInOneThread(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| public long ChangePlayerStateInOneThread(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| { | { | ||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| @@ -347,17 +347,18 @@ namespace GameClass.GameObj | |||||
| IsMoving = false; | IsMoving = false; | ||||
| playerState = (value == PlayerStateType.Moving) ? PlayerStateType.Null : value; | playerState = (value == PlayerStateType.Moving) ? PlayerStateType.Null : value; | ||||
| //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | //Debugger.Output(this,playerState.ToString()+" "+IsMoving.ToString()); | ||||
| return stateNum; | |||||
| } | } | ||||
| } | } | ||||
| public void SetPlayerStateNaturally() | |||||
| public long SetPlayerStateNaturally() | |||||
| { | { | ||||
| lock (actionLock) | lock (actionLock) | ||||
| { | { | ||||
| ++stateNum; | |||||
| whatInteractingWith = null; | whatInteractingWith = null; | ||||
| IsMoving = false; | IsMoving = false; | ||||
| playerState = PlayerStateType.Null; | playerState = PlayerStateType.Null; | ||||
| return ++stateNum; | |||||
| } | } | ||||
| } | } | ||||
| @@ -18,6 +18,10 @@ namespace GameClass.GameObj | |||||
| lock (actionLock) | lock (actionLock) | ||||
| return stateNum; | return stateNum; | ||||
| } | } | ||||
| set | |||||
| { | |||||
| lock (actionLock) stateNum = value; | |||||
| } | |||||
| } | } | ||||
| //规定moveReaderWriterLock>actionLock | //规定moveReaderWriterLock>actionLock | ||||
| @@ -73,14 +73,12 @@ namespace GameEngine | |||||
| obj.MovingSetPos(new XY(moveVec, maxLen)); | obj.MovingSetPos(new XY(moveVec, maxLen)); | ||||
| } | } | ||||
| public void MoveObj(IMoveable obj, int moveTime, double direction) | |||||
| public void MoveObj(IMoveable obj, int moveTime, double direction, long threadNum) | |||||
| { | { | ||||
| if (!gameTimer.IsGaming) return; | if (!gameTimer.IsGaming) return; | ||||
| long threadNum; | |||||
| lock (obj.ActionLock) | lock (obj.ActionLock) | ||||
| { | { | ||||
| if (!obj.IsAvailableForMove) return; | if (!obj.IsAvailableForMove) return; | ||||
| threadNum = obj.StateNum; | |||||
| obj.IsMoving = true; | obj.IsMoving = true; | ||||
| } | } | ||||
| new Thread | new Thread | ||||
| @@ -89,7 +87,7 @@ namespace GameEngine | |||||
| { | { | ||||
| double moveVecLength = 0.0; | double moveVecLength = 0.0; | ||||
| XY res = new(direction, moveVecLength); | XY res = new(direction, moveVecLength); | ||||
| double deltaLen = moveVecLength - Math.Sqrt(obj.MovingSetPos(res)); // 转向,并用deltaLen存储行走的误差 | |||||
| double deltaLen = 0; // 转向,并用deltaLen存储行走的误差 | |||||
| IGameObj? collisionObj = null; | IGameObj? collisionObj = null; | ||||
| bool isDestroyed = false; | bool isDestroyed = false; | ||||
| @@ -125,7 +123,7 @@ namespace GameEngine | |||||
| res = new XY(direction, moveVecLength); | res = new XY(direction, moveVecLength); | ||||
| //对人特殊处理 | //对人特殊处理 | ||||
| if (threadNum > 0 && ((ICharacter)obj).StateNum != threadNum) return false; | |||||
| if (threadNum > 0 && obj.StateNum != threadNum) return false; | |||||
| // 越界情况处理:如果越界,则与越界方块碰撞 | // 越界情况处理:如果越界,则与越界方块碰撞 | ||||
| bool flag; // 循环标志 | bool flag; // 循环标志 | ||||
| @@ -146,7 +144,7 @@ namespace GameEngine | |||||
| isDestroyed = true; | isDestroyed = true; | ||||
| return false; | return false; | ||||
| case AfterCollision.MoveMax: | case AfterCollision.MoveMax: | ||||
| if (threadNum == 0 || ((ICharacter)obj).StateNum == threadNum) | |||||
| if (threadNum == 0 || obj.StateNum == threadNum) | |||||
| MoveMax(obj, res); | MoveMax(obj, res); | ||||
| moveVecLength = 0; | moveVecLength = 0; | ||||
| res = new XY(direction, moveVecLength); | res = new XY(direction, moveVecLength); | ||||
| @@ -154,7 +152,7 @@ namespace GameEngine | |||||
| } | } | ||||
| } while (flag); | } while (flag); | ||||
| if (threadNum == 0 || ((ICharacter)obj).StateNum == threadNum) | |||||
| if (threadNum == 0 || obj.StateNum == threadNum) | |||||
| deltaLen += moveVecLength - Math.Sqrt(obj.MovingSetPos(res)); | deltaLen += moveVecLength - Math.Sqrt(obj.MovingSetPos(res)); | ||||
| return true; | return true; | ||||
| @@ -173,7 +171,7 @@ namespace GameEngine | |||||
| res = new XY(direction, moveVecLength); | res = new XY(direction, moveVecLength); | ||||
| if ((collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res)) == null) | if ((collisionObj = collisionChecker.CheckCollisionWhenMoving(obj, res)) == null) | ||||
| { | { | ||||
| if (threadNum == 0 || ((ICharacter)obj).StateNum == threadNum) | |||||
| if (threadNum == 0 || obj.StateNum == threadNum) | |||||
| obj.MovingSetPos(res); | obj.MovingSetPos(res); | ||||
| } | } | ||||
| else | else | ||||
| @@ -188,7 +186,7 @@ namespace GameEngine | |||||
| isDestroyed = true; | isDestroyed = true; | ||||
| break; | break; | ||||
| case AfterCollision.MoveMax: | case AfterCollision.MoveMax: | ||||
| if (threadNum == 0 || ((ICharacter)obj).StateNum == threadNum) | |||||
| if (threadNum == 0 || obj.StateNum == threadNum) | |||||
| MoveMax(obj, res); | MoveMax(obj, res); | ||||
| moveVecLength = 0; | moveVecLength = 0; | ||||
| res = new XY(direction, moveVecLength); | res = new XY(direction, moveVecLength); | ||||
| @@ -38,8 +38,8 @@ namespace Gaming | |||||
| if (moveTimeInMilliseconds < 5) return false; | if (moveTimeInMilliseconds < 5) return false; | ||||
| if (!playerToMove.Commandable()) return false; | if (!playerToMove.Commandable()) return false; | ||||
| if (playerToMove.IsMoving) return false; | if (playerToMove.IsMoving) return false; | ||||
| characterManager.SetPlayerState(playerToMove, PlayerStateType.Moving); | |||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); | |||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, | |||||
| characterManager.SetPlayerState(playerToMove, PlayerStateType.Moving)); | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -47,7 +47,7 @@ namespace Gaming | |||||
| { | { | ||||
| if (!playerToMove.Commandable() && playerToMove.PlayerState != PlayerStateType.Stunned) return false; | if (!playerToMove.Commandable() && playerToMove.PlayerState != PlayerStateType.Stunned) return false; | ||||
| characterManager.BeStunned(playerToMove, moveTimeInMilliseconds); | characterManager.BeStunned(playerToMove, moveTimeInMilliseconds); | ||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection); | |||||
| moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection, playerToMove.StateNum); | |||||
| return true; | return true; | ||||
| } | } | ||||
| @@ -326,7 +326,7 @@ namespace Gaming | |||||
| player.ReSetPos(windowToPlayer + windowForClimb.Position); | player.ReSetPos(windowToPlayer + windowForClimb.Position); | ||||
| player.MoveSpeed = player.SpeedOfClimbingThroughWindows; | player.MoveSpeed = player.SpeedOfClimbingThroughWindows; | ||||
| moveEngine.MoveObj(player, (int)(windowToPlayer.Length() * 3.0 * 1000 / player.MoveSpeed), (-1 * windowToPlayer).Angle()); | |||||
| moveEngine.MoveObj(player, (int)(windowToPlayer.Length() * 3.0 * 1000 / player.MoveSpeed), (-1 * windowToPlayer).Angle(), threadNum); | |||||
| new FrameRateTaskExecutor<int>( | new FrameRateTaskExecutor<int>( | ||||
| loopCondition: () => threadNum == player.StateNum && gameMap.Timer.IsGaming, | loopCondition: () => threadNum == player.StateNum && gameMap.Timer.IsGaming, | ||||
| @@ -43,11 +43,11 @@ namespace Gaming | |||||
| { | { | ||||
| // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange | ||||
| if (bulletType == BulletType.Null) return; | if (bulletType == BulletType.Null) return; | ||||
| Bullet? bullet = BulletFactory.GetBullet(player, pos); | |||||
| Bullet? bullet = BulletFactory.GetBullet(player, pos, bulletType); | |||||
| if (bullet == null) return; | if (bullet == null) return; | ||||
| Debugger.Output(bullet, "Attack in " + pos.ToString()); | Debugger.Output(bullet, "Attack in " + pos.ToString()); | ||||
| gameMap.Add(bullet); | gameMap.Add(bullet); | ||||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle, ++bullet.StateNum); // 这里时间参数除出来的单位要是ms | |||||
| } | } | ||||
| private void BombObj(Bullet bullet, GameObj objBeingShot) | private void BombObj(Bullet bullet, GameObj objBeingShot) | ||||
| @@ -195,7 +195,7 @@ namespace Gaming | |||||
| { | { | ||||
| Debugger.Output(bullet, "Attack in " + bullet.Position.ToString()); | Debugger.Output(bullet, "Attack in " + bullet.Position.ToString()); | ||||
| gameMap.Add(bullet); | gameMap.Add(bullet); | ||||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle, ++bullet.StateNum); // 这里时间参数除出来的单位要是ms | |||||
| if (bullet.CastTime > 0) | if (bullet.CastTime > 0) | ||||
| { | { | ||||
| characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); | characterManager.SetPlayerState(player, PlayerStateType.TryingToAttack); | ||||
| @@ -17,7 +17,7 @@ namespace Gaming | |||||
| this.gameMap = gameMap; | this.gameMap = gameMap; | ||||
| } | } | ||||
| public void SetPlayerState(Character player, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| public long SetPlayerState(Character player, PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null) | |||||
| { | { | ||||
| lock (player.ActionLock) | lock (player.ActionLock) | ||||
| { | { | ||||
| @@ -25,29 +25,24 @@ namespace Gaming | |||||
| { | { | ||||
| case PlayerStateType.OpeningTheChest: | case PlayerStateType.OpeningTheChest: | ||||
| ((Chest)player.WhatInteractingWith!).StopOpen(); | ((Chest)player.WhatInteractingWith!).StopOpen(); | ||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| return player.ChangePlayerState(value, gameObj); | |||||
| case PlayerStateType.OpeningTheDoorway: | case PlayerStateType.OpeningTheDoorway: | ||||
| Doorway doorway = (Doorway)player.WhatInteractingWith!; | Doorway doorway = (Doorway)player.WhatInteractingWith!; | ||||
| doorway.OpenDegree += gameMap.Timer.nowTime() - doorway.OpenStartTime; | doorway.OpenDegree += gameMap.Timer.nowTime() - doorway.OpenStartTime; | ||||
| doorway.OpenStartTime = 0; | doorway.OpenStartTime = 0; | ||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| return player.ChangePlayerState(value, gameObj); | |||||
| case PlayerStateType.Addicted: | case PlayerStateType.Addicted: | ||||
| if (value == PlayerStateType.Rescued) | if (value == PlayerStateType.Rescued) | ||||
| player.ChangePlayerStateInOneThread(value, gameObj); | |||||
| return player.ChangePlayerStateInOneThread(value, gameObj); | |||||
| else | else | ||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| return player.ChangePlayerState(value, gameObj); | |||||
| case PlayerStateType.Rescued: | case PlayerStateType.Rescued: | ||||
| if (value == PlayerStateType.Addicted) | if (value == PlayerStateType.Addicted) | ||||
| player.ChangePlayerStateInOneThread(value, gameObj); | |||||
| return player.ChangePlayerStateInOneThread(value, gameObj); | |||||
| else | else | ||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| return player.ChangePlayerState(value, gameObj); | |||||
| default: | default: | ||||
| player.ChangePlayerState(value, gameObj); | |||||
| break; | |||||
| return player.ChangePlayerState(value, gameObj); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||