|
|
|
@@ -16,13 +16,13 @@ namespace Gaming |
|
|
|
public uint birthPointIndex; |
|
|
|
public long teamID; |
|
|
|
public long playerID; |
|
|
|
public PassiveSkillType passiveSkill; |
|
|
|
public CharacterType characterType; |
|
|
|
public ActiveSkillType commonSkill; |
|
|
|
public PlayerInitInfo(uint birthPointIndex, long teamID, long playerID, PassiveSkillType passiveSkill, ActiveSkillType commonSkill) |
|
|
|
public PlayerInitInfo(uint birthPointIndex, long teamID, long playerID, CharacterType characterType, ActiveSkillType commonSkill) |
|
|
|
{ |
|
|
|
this.birthPointIndex = birthPointIndex; |
|
|
|
this.teamID = teamID; |
|
|
|
this.passiveSkill = passiveSkill; |
|
|
|
this.characterType = characterType; |
|
|
|
this.commonSkill = commonSkill; |
|
|
|
this.playerID = playerID; |
|
|
|
} |
|
|
|
@@ -40,9 +40,9 @@ namespace Gaming |
|
|
|
|| gameMap.BirthPointList[playerInitInfo.birthPointIdx].Parent != null)*/ |
|
|
|
return GameObj.invalidID; |
|
|
|
|
|
|
|
XYPosition pos = gameMap.BirthPointList[playerInitInfo.birthPointIndex].Position; |
|
|
|
XY pos = gameMap.BirthPointList[playerInitInfo.birthPointIndex].Position; |
|
|
|
// Console.WriteLine($"x,y: {pos.x},{pos.y}"); |
|
|
|
Character newPlayer = new(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.passiveSkill, playerInitInfo.commonSkill); |
|
|
|
Character newPlayer = new(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.characterType, playerInitInfo.commonSkill); |
|
|
|
gameMap.BirthPointList[playerInitInfo.birthPointIndex].Parent = newPlayer; |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); |
|
|
|
try |
|
|
|
@@ -64,62 +64,62 @@ namespace Gaming |
|
|
|
{ |
|
|
|
while (!gameMap.Timer.IsGaming) |
|
|
|
Thread.Sleep(newPlayer.CD); |
|
|
|
long lastTime = Environment.TickCount64; |
|
|
|
new FrameRateTaskExecutor<int>( |
|
|
|
loopCondition: () => gameMap.Timer.IsGaming, |
|
|
|
loopToDo: () => |
|
|
|
{ |
|
|
|
if (!newPlayer.IsResetting) |
|
|
|
long lastTime = Environment.TickCount64; |
|
|
|
new FrameRateTaskExecutor<int>( |
|
|
|
loopCondition: () => gameMap.Timer.IsGaming, |
|
|
|
loopToDo: () => |
|
|
|
{ |
|
|
|
if (!newPlayer.IsResetting) |
|
|
|
{ |
|
|
|
long nowTime = Environment.TickCount64; |
|
|
|
if (newPlayer.BulletNum == newPlayer.MaxBulletNum) |
|
|
|
lastTime = nowTime; |
|
|
|
if (nowTime - lastTime >= newPlayer.CD) |
|
|
|
{ |
|
|
|
_ = newPlayer.TryAddBulletNum(); |
|
|
|
lastTime = nowTime; |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
timeInterval: GameData.checkInterval, |
|
|
|
finallyReturn: () => 0 |
|
|
|
) |
|
|
|
{ |
|
|
|
long nowTime = Environment.TickCount64; |
|
|
|
if (newPlayer.BulletNum == newPlayer.MaxBulletNum) |
|
|
|
lastTime = nowTime; |
|
|
|
if (nowTime - lastTime >= newPlayer.CD) |
|
|
|
AllowTimeExceed = true |
|
|
|
/*MaxTolerantTimeExceedCount = 5, |
|
|
|
TimeExceedAction = exceedTooMuch => |
|
|
|
{ |
|
|
|
_ = newPlayer.TryAddBulletNum(); |
|
|
|
lastTime = nowTime; |
|
|
|
} |
|
|
|
if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!"); |
|
|
|
}*/ |
|
|
|
} |
|
|
|
}, |
|
|
|
timeInterval: GameData.checkInterval, |
|
|
|
finallyReturn: () => 0 |
|
|
|
) { |
|
|
|
AllowTimeExceed = true |
|
|
|
/*MaxTolerantTimeExceedCount = 5, |
|
|
|
TimeExceedAction = exceedTooMuch => |
|
|
|
{ |
|
|
|
if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!"); |
|
|
|
}*/ |
|
|
|
} |
|
|
|
.Start(); |
|
|
|
} |
|
|
|
.Start(); |
|
|
|
} |
|
|
|
) |
|
|
|
{ IsBackground = true }.Start(); |
|
|
|
|
|
|
|
return newPlayer.ID; |
|
|
|
} |
|
|
|
public bool StartGame(int milliSeconds) |
|
|
|
{ |
|
|
|
} |
|
|
|
public bool StartGame(int milliSeconds) |
|
|
|
{ |
|
|
|
if (gameMap.Timer.IsGaming) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
{ |
|
|
|
player.CanMove = true; |
|
|
|
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
{ |
|
|
|
player.CanMove = true; |
|
|
|
|
|
|
|
player.AddShield(GameData.shieldTimeAtBirth); |
|
|
|
} |
|
|
|
player.AddShield(GameData.shieldTimeAtBirth); |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock(); |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock(); |
|
|
|
} |
|
|
|
|
|
|
|
propManager.StartProducing(); |
|
|
|
gemManager.StartProducingGem(); |
|
|
|
new Thread |
|
|
|
new Thread |
|
|
|
( |
|
|
|
() => |
|
|
|
{ |
|
|
|
@@ -128,24 +128,24 @@ namespace Gaming |
|
|
|
loopCondition: () => gameMap.Timer.IsGaming, |
|
|
|
loopToDo: () => |
|
|
|
{ |
|
|
|
foreach (var kvp in gameMap.GameObjDict) // 检查物体位置 |
|
|
|
{ |
|
|
|
if (kvp.Key == GameObjIdx.Bullet || kvp.Key == GameObjIdx.Player || kvp.Key == GameObjIdx.Prop || kvp.Key == GameObjIdx.Gem) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[kvp.Key].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
foreach (var item in gameMap.GameObjDict[kvp.Key]) |
|
|
|
{ |
|
|
|
item.Place = gameMap.GetPlaceType(item.Position); |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[kvp.Key].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
foreach (var kvp in gameMap.GameObjDict) // 检查物体位置 |
|
|
|
{ |
|
|
|
if (kvp.Key == GameObjIdx.Bullet || kvp.Key == GameObjIdx.Player || kvp.Key == GameObjIdx.Prop) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[kvp.Key].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
foreach (var item in gameMap.GameObjDict[kvp.Key]) |
|
|
|
{ |
|
|
|
item.Place = gameMap.GetPlaceType(item.Position); |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[kvp.Key].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
timeInterval: GameData.checkInterval, |
|
|
|
finallyReturn: () => 0 |
|
|
|
@@ -153,228 +153,192 @@ namespace Gaming |
|
|
|
{ |
|
|
|
AllowTimeExceed = true |
|
|
|
}.Start(); |
|
|
|
} |
|
|
|
} |
|
|
|
) |
|
|
|
{ IsBackground = true }.Start(); |
|
|
|
// 开始游戏 |
|
|
|
if (!gameMap.Timer.StartGame(milliSeconds)) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
|
|
|
|
EndGame(); // 游戏结束时要做的事 |
|
|
|
|
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void EndGame() |
|
|
|
{ |
|
|
|
public void EndGame() |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); |
|
|
|
try |
|
|
|
/*try |
|
|
|
{ |
|
|
|
foreach (var player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
{ |
|
|
|
gemManager.UseAllGem((Character)player); |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
}*/ |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle) |
|
|
|
{ |
|
|
|
|
|
|
|
} |
|
|
|
public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
moveManager.MovePlayer(player, moveTimeInMilliseconds, angle); |
|
|
|
moveManager.MovePlayer(player, moveTimeInMilliseconds, angle); |
|
|
|
#if DEBUG |
|
|
|
Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!"); |
|
|
|
Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
#if DEBUG |
|
|
|
Console.WriteLine($"PlayerID:{playerID} player does not exists!"); |
|
|
|
Console.WriteLine($"PlayerID:{playerID} player does not exists!"); |
|
|
|
#endif |
|
|
|
} |
|
|
|
} |
|
|
|
public void Attack(long playerID, double angle) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
_ = attackManager.Attack(player, angle); |
|
|
|
} |
|
|
|
} |
|
|
|
public void UseGem(long playerID, int num = int.MaxValue) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
gemManager.UseGem(player, num); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
public void ThrowGem(long playerID, int moveMilliTime, double angle, int size = 1) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
gemManager.ThrowGem(player, moveMilliTime, angle, size); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
public bool PickGem(long playerID) |
|
|
|
{ |
|
|
|
} |
|
|
|
public void Attack(long playerID, double angle) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return false; |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
return gemManager.PickGem(player); |
|
|
|
_ = attackManager.Attack(player, angle); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
public void UseProp(long playerID) |
|
|
|
{ |
|
|
|
} |
|
|
|
public void UseProp(long playerID) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
propManager.UseProp(player); |
|
|
|
propManager.UseProp(player); |
|
|
|
} |
|
|
|
} |
|
|
|
public void ThrowProp(long playerID, int timeInmillionSeconds, double angle) |
|
|
|
{ |
|
|
|
} |
|
|
|
public void ThrowProp(long playerID, int timeInmillionSeconds, double angle) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
return; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
propManager.ThrowProp(player, timeInmillionSeconds, angle); |
|
|
|
propManager.ThrowProp(player, timeInmillionSeconds, angle); |
|
|
|
} |
|
|
|
} |
|
|
|
public bool PickProp(long playerID, PropType propType = PropType.Null) |
|
|
|
{ |
|
|
|
} |
|
|
|
public bool PickProp(long playerID, PropType propType = PropType.Null) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
return propManager.PickProp(player, propType); |
|
|
|
return propManager.PickProp(player, propType); |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public bool UseCommonSkill(long playerID) |
|
|
|
{ |
|
|
|
public bool UseCommonSkill(long playerID) |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return false; |
|
|
|
return false; |
|
|
|
Character? player = gameMap.FindPlayer(playerID); |
|
|
|
if (player != null) |
|
|
|
{ |
|
|
|
return skillManager.UseCommonSkill(player); |
|
|
|
return skillManager.UseCommonSkill(player); |
|
|
|
} |
|
|
|
else |
|
|
|
return false; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
public void AllPlayerUsePassiveSkill() |
|
|
|
{ |
|
|
|
public void AllPlayerUsePassiveSkill() |
|
|
|
{ |
|
|
|
if (!gameMap.Timer.IsGaming) |
|
|
|
return; |
|
|
|
return; |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
{ |
|
|
|
skillManager.UsePassiveSkill(player); |
|
|
|
} |
|
|
|
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
{ |
|
|
|
skillManager.UsePassiveSkill(player); |
|
|
|
} |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); |
|
|
|
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public void ClearLists(GameObjIdx[] objIdxes) |
|
|
|
{ |
|
|
|
public void ClearLists(GameObjIdx[] objIdxes) |
|
|
|
{ |
|
|
|
foreach (var idx in objIdxes) |
|
|
|
{ |
|
|
|
if (idx != GameObjIdx.None) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[idx].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
gameMap.GameObjDict[idx].Clear(); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[idx].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (idx != GameObjIdx.None) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[idx].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
gameMap.GameObjDict[idx].Clear(); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[idx].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
public void ClearAllLists() |
|
|
|
{ |
|
|
|
} |
|
|
|
public void ClearAllLists() |
|
|
|
{ |
|
|
|
foreach (var keyValuePair in gameMap.GameObjDict) |
|
|
|
{ |
|
|
|
if (keyValuePair.Key != GameObjIdx.Map) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
if (keyValuePair.Key == GameObjIdx.Player) |
|
|
|
if (keyValuePair.Key != GameObjIdx.Map) |
|
|
|
{ |
|
|
|
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
player.CanMove = false; |
|
|
|
if (keyValuePair.Key == GameObjIdx.Player) |
|
|
|
{ |
|
|
|
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player]) |
|
|
|
{ |
|
|
|
player.CanMove = false; |
|
|
|
} |
|
|
|
} |
|
|
|
gameMap.GameObjDict[keyValuePair.Key].Clear(); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
gameMap.GameObjDict[keyValuePair.Key].Clear(); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public int GetTeamScore(long teamID) |
|
|
|
{ |
|
|
|
public int GetTeamScore(long teamID) |
|
|
|
{ |
|
|
|
return teamList[(int)teamID].Score; |
|
|
|
} |
|
|
|
public List<IGameObj> GetGameObj() |
|
|
|
{ |
|
|
|
} |
|
|
|
public List<IGameObj> GetGameObj() |
|
|
|
{ |
|
|
|
var gameObjList = new List<IGameObj>(); |
|
|
|
foreach (var keyValuePair in gameMap.GameObjDict) |
|
|
|
{ |
|
|
|
if (keyValuePair.Key != GameObjIdx.Map) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (keyValuePair.Key != GameObjIdx.Map) |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock(); |
|
|
|
try |
|
|
|
{ |
|
|
|
gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]); |
|
|
|
} |
|
|
|
finally |
|
|
|
{ |
|
|
|
gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return gameObjList; |
|
|
|
} |
|
|
|
public Game(uint[,] mapResource, int numOfTeam) |
|
|
|
{ |
|
|
|
} |
|
|
|
public Game(uint[,] mapResource, int numOfTeam) |
|
|
|
{ |
|
|
|
// if (numOfTeam > maxTeamNum) throw new TeamNumOverFlowException(); |
|
|
|
|
|
|
|
gameMap = new Map(mapResource); |
|
|
|
@@ -384,14 +348,13 @@ public Game(uint[,] mapResource, int numOfTeam) |
|
|
|
teamList = new List<Team>(); |
|
|
|
for (int i = 0; i < numOfTeam; ++i) |
|
|
|
{ |
|
|
|
teamList.Add(new Team()); |
|
|
|
teamList.Add(new Team()); |
|
|
|
} |
|
|
|
|
|
|
|
skillManager = new SkillManager(); |
|
|
|
attackManager = new AttackManager(gameMap); |
|
|
|
moveManager = new MoveManager(gameMap); |
|
|
|
propManager = new PropManager(gameMap); |
|
|
|
gemManager = new GemManager(gameMap); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |