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