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