| @@ -2,8 +2,6 @@ | |||
| using Preparation.Utility; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Runtime.CompilerServices; | |||
| using System.Threading; | |||
| namespace GameClass.GameObj | |||
| { | |||
| @@ -99,6 +97,7 @@ namespace GameClass.GameObj | |||
| ); | |||
| Bullet? bullet = BulletFactory.GetBullet(this, res); | |||
| if (bullet == null) return null; | |||
| bullet.AP += TryAddAp() ? GameData.ApPropAdd : 0; | |||
| facingDirection = new(angle, bullet.AttackDistance); | |||
| return bullet; | |||
| } | |||
| @@ -371,7 +370,7 @@ namespace GameClass.GameObj | |||
| { | |||
| playerState = playerStateType; | |||
| canMove = false; | |||
| isResetting = true; | |||
| isRemoved = true; | |||
| position = GameData.PosWhoDie; | |||
| } | |||
| } | |||
| @@ -620,7 +619,7 @@ namespace GameClass.GameObj | |||
| public override ShapeType Shape => ShapeType.Circle; | |||
| public override bool IgnoreCollideExecutor(IGameObj targetObj) | |||
| { | |||
| if (IsResetting) | |||
| if (IsRemoved) | |||
| return true; | |||
| if (targetObj.Type == GameObjType.Prop) | |||
| { | |||
| @@ -108,15 +108,15 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| protected bool isResetting; | |||
| public bool IsResetting | |||
| protected bool isRemoved; | |||
| public bool IsRemoved | |||
| { | |||
| get | |||
| { | |||
| moveReaderWriterLock.EnterReadLock(); | |||
| try | |||
| { | |||
| return isResetting; | |||
| return isRemoved; | |||
| } | |||
| finally | |||
| { | |||
| @@ -125,7 +125,22 @@ namespace GameClass.GameObj | |||
| } | |||
| } | |||
| public bool IsAvailable => !IsMoving && CanMove && !IsResetting; // 是否能接收指令 | |||
| public bool IsAvailableForMove // 是否能接收移动指令 | |||
| { | |||
| get | |||
| { | |||
| moveReaderWriterLock.EnterReadLock(); | |||
| try | |||
| { | |||
| lock (actionLock) | |||
| return !isMoving && canMove && !isRemoved; | |||
| } | |||
| finally | |||
| { | |||
| moveReaderWriterLock.ExitReadLock(); | |||
| } | |||
| } | |||
| } | |||
| protected int moveSpeed; | |||
| /// <summary> | |||
| @@ -176,7 +191,7 @@ namespace GameClass.GameObj | |||
| this.FacingDirection = new XY(1, 0); | |||
| isMoving = false; | |||
| CanMove = false; | |||
| IsResetting = true; | |||
| IsRemoved = true; | |||
| this.Position = birthPos; | |||
| this.Place= place; | |||
| } | |||
| @@ -75,19 +75,18 @@ namespace GameEngine | |||
| public void MoveObj(IMoveable obj, int moveTime, double direction) | |||
| { | |||
| if (obj.IsMoving) // 已经移动的物体不能再移动 | |||
| return; | |||
| if (!obj.IsAvailable || !gameTimer.IsGaming) | |||
| return; | |||
| long threadNum = (obj.Type == GameObjType.Character) ? ((ICharacter)obj).StateNum : 0;//对人特殊处理 | |||
| if (!gameTimer.IsGaming) return; | |||
| long threadNum; | |||
| lock (obj.ActionLock) | |||
| { | |||
| if (!obj.IsAvailableForMove) return; | |||
| threadNum = obj.StateNum; | |||
| obj.IsMoving = true; | |||
| } | |||
| new Thread | |||
| ( | |||
| () => | |||
| { | |||
| lock (obj.ActionLock) | |||
| obj.IsMoving = true; | |||
| double moveVecLength = 0.0; | |||
| XY res = new(direction, moveVecLength); | |||
| double deltaLen = moveVecLength - Math.Sqrt(obj.MovingSetPos(res)); // 转向,并用deltaLen存储行走的误差 | |||
| @@ -119,7 +118,7 @@ namespace GameEngine | |||
| if (!isDestroyed) | |||
| { | |||
| new FrameRateTaskExecutor<int>( | |||
| () => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting && obj.IsMoving, | |||
| () => gameTimer.IsGaming && obj.CanMove && !obj.IsRemoved && obj.IsMoving, | |||
| () => | |||
| { | |||
| moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond; | |||
| @@ -194,7 +194,6 @@ namespace Gaming | |||
| if (bullet != null) | |||
| { | |||
| Debugger.Output(bullet, "Attack in " + bullet.Position.ToString()); | |||
| bullet.AP += player.TryAddAp() ? GameData.ApPropAdd : 0; | |||
| gameMap.Add(bullet); | |||
| moveEngine.MoveObj(bullet, (int)(bullet.AttackDistance * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms | |||
| if (bullet.CastTime > 0) | |||
| @@ -74,7 +74,7 @@ namespace Gaming | |||
| Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval)); | |||
| long lastTime = Environment.TickCount64; | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, | |||
| loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsRemoved, | |||
| loopToDo: () => | |||
| { | |||
| long nowTime = Environment.TickCount64; | |||
| @@ -132,7 +132,7 @@ namespace Gaming | |||
| } | |||
| } | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsResetting, | |||
| loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsRemoved, | |||
| loopToDo: () => | |||
| { | |||
| gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock(); | |||
| @@ -21,7 +21,7 @@ namespace Gaming | |||
| public void UseProp(Character player, PropType propType) | |||
| { | |||
| if (player.IsResetting || player.CharacterType == CharacterType.Robot) | |||
| if (player.IsRemoved || player.CharacterType == CharacterType.Robot) | |||
| return; | |||
| Prop prop = player.UseProp(propType); | |||
| switch (prop.GetPropType()) | |||
| @@ -73,7 +73,7 @@ namespace Gaming | |||
| /// <returns></returns> | |||
| public bool PickProp(Character player, PropType propType = PropType.Null) | |||
| { | |||
| if (player.IsResetting) | |||
| if (player.IsRemoved) | |||
| return false; | |||
| int indexing = player.IndexingOfAddProp(); | |||
| if (indexing == GameData.maxNumOfPropInPropInventory) | |||
| @@ -118,7 +118,7 @@ namespace Gaming | |||
| public void ThrowProp(Character player, PropType propType) | |||
| { | |||
| if (!gameMap.Timer.IsGaming || player.IsResetting) | |||
| if (!gameMap.Timer.IsGaming || player.IsRemoved) | |||
| return; | |||
| Prop prop = player.UseProp(propType); | |||
| if (prop.GetPropType() == PropType.Null) | |||
| @@ -335,7 +335,7 @@ namespace Gaming | |||
| startSkill(); | |||
| activeSkill.IsBeingUsed = true; | |||
| new FrameRateTaskExecutor<int>( | |||
| () => !player.IsResetting, | |||
| () => !player.IsRemoved, | |||
| () => | |||
| { | |||
| player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); | |||
| @@ -355,7 +355,7 @@ namespace Gaming | |||
| Debugger.Output(player, "return to normal."); | |||
| new FrameRateTaskExecutor<int>( | |||
| loopCondition: () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsResetting, | |||
| loopCondition: () => player.TimeUntilActiveSkillAvailable[activeSkillType] > 0 && !player.IsRemoved, | |||
| loopToDo: () => | |||
| { | |||
| player.AddTimeUntilActiveSkillAvailable(activeSkillType, -(int)GameData.frameDuration); | |||
| @@ -22,7 +22,7 @@ namespace Gaming // 被动技能开局时就释放,持续到游戏结束 | |||
| { | |||
| new FrameRateTaskExecutor<int> | |||
| ( | |||
| () => gameMap.Timer.IsGaming && !player.IsResetting, | |||
| () => gameMap.Timer.IsGaming && !player.IsRemoved, | |||
| () => | |||
| { | |||
| if (player.Commandable() && player.PlayerState != PlayerStateType.Fixing) activeSkill.DegreeOfMeditation += learningDegree * GameData.frameDuration; | |||
| @@ -14,7 +14,6 @@ namespace Preparation.Interface | |||
| public BulletType BulletOfPlayer { get; set; } | |||
| public CharacterType CharacterType { get; } | |||
| public int UpdateBulletNum(int time); | |||
| public long StateNum { get; } | |||
| public bool IsGhost(); | |||
| } | |||
| @@ -8,8 +8,9 @@ namespace Preparation.Interface | |||
| object ActionLock { get; } | |||
| public int MoveSpeed { get; } | |||
| public bool IsMoving { get; set; } | |||
| public bool IsResetting { get; } // reviving | |||
| public bool IsAvailable { get; } | |||
| public bool IsRemoved { get; } | |||
| public bool IsAvailableForMove { get; } | |||
| public long StateNum { get; } | |||
| public long MovingSetPos(XY moveVec); | |||
| public void ReSetCanMove(bool value); | |||
| public bool WillCollideWith(IGameObj? targetObj, XY nextPos) // 检查下一位置是否会和目标物碰撞 | |||