/// <summary> /// Track game world operations that are not high priority to react in realtime /// </summary> private void GeneralGameFlowThread() { try { while (_isRunning) { if (GameMaster.IsGamePaused == false && _localPause == false) { foreach (var npc in NpCsOnMap) { var mapTiles = WorldMap.FloorObjects.Select(tiles => tiles.Position) .Where(tile => tile.Y >= (npc.Position.Y + npc.Height)).ToList(); if (mapTiles.Count <= 0) { continue; } var sortedTiles = SortByDistance(npc.Position, mapTiles); var closetTilePos = sortedTiles[0]; var closestTile = WorldMap.FloorObjects.First(tile => tile.Position.Equals(closetTilePos)); if (bool.Parse(closestTile.Properties["leftNeighbor"]) == false) { npc.IsNearEdge = true; npc.TurnRight = true; npc.TurnLeft = false; } else if (bool.Parse(closestTile.Properties["rightNeighbor"]) == false) { npc.IsNearEdge = true; npc.TurnRight = false; npc.TurnLeft = true; } else { npc.IsNearEdge = false; npc.TurnRight = false; npc.TurnLeft = false; } } } if (GameMaster.IsGamePaused || IsInitialMapLoad || _localPause) { continue; } if (WorldPlayer == null) { LogManager.LogError("The world player is null, aborting gen game flow"); _isRunning = false; break; } if (WorldPlayer.Health <= 0) { WorldPlayer.DeathSound.Play(); Pause(); NumberOfPlayerLives--; Reset(NumberOfPlayerLives, false); UnpauseWorld(); } if (NumberOfPlayerLives <= 0) { WorldPlayer.DeathSound.Play(); Pause(); WorldMap = AssetManager.LoadGameMap(0, _worldView); Reset(3, true); UnpauseWorld(); } var tmp = new List <MapItem>(WorldMap.ItemsOnMap); var tmpArry = tmp.ToArray(); foreach (var item in tmpArry) { if (WorldPlayer.IsIntersecting(item.Position) == false) { continue; } if (item.IsHealth && WorldPlayer.Health < 100) { WorldPlayer.Health += 5; } Score += item.Points; tmp.Remove(item); } WorldMap.ItemsOnMap = tmp; if (WorldPlayer.ChangePlayer) { _localPause = true; ChangePlayer(); _localPause = false; } if (WorldPlayer.IsIntersecting(WorldMap.EndOfMap) == false) { _madeItToEnd = false; continue; } _finishMapSound.Play(); _madeItToEnd = true; _localPause = true; } } catch (ThreadAbortException) { } finally { LogManager.LogWarning("Aborting general game flow thread."); } }
/// <summary> /// Detect sprite collisions and ground collisions /// </summary> private void CollisionDetection() { if (WorldMap.FloorObjects == null || WorldMap.FloorObjects.Count == 0) { _isRunning = false; LogManager.LogError("Could not find floor objects for collision detection."); WorldPlayer.IsGroundUnderMe = true; } try { while (_isRunning) { if (GameMaster.IsGamePaused || IsInitialMapLoad || _localPause) { continue; } /* * Find the ground tiles closest to the player * Calculate the distance between the player and said tile * if that distance is greater than the size of tile then * the player needs to fall */ if (WorldMap.FloorObjects != null && WorldMap.FloorObjects.Count != 0) { DictateSpriteFalling(WorldPlayer); } else { LogManager.LogError("No floor found on: " + WorldMap.Name); } if (WorldPlayer.IsGroundUnderMe == false && WorldPlayer.TimeFalling >= (2.5f * 0.92f)) { // if player is falling for too long, reset them WorldPlayer.DeathSound.Play(); Pause(); NumberOfPlayerLives--; Reset(NumberOfPlayerLives, false); UnpauseWorld(); continue; } var tmp = new List <Shot>(WorldPlayer.ShotsFired); var tmpArry = tmp.ToArray(); foreach (var shot in tmpArry) { var endOfScreen = _worldView.Center.X - shot.Width + _worldView.Size.X / 2.0f; if (shot.Position.X >= endOfScreen) { tmp.Remove(shot); continue; } if (shot.TotalTimeDrawn >= MaxTimeForBulletDraw) { tmp.Remove(shot); continue; } var center = _worldView.Center; var viewSize = _worldView.Size; EnemiesRendered = EnemiesOnMap.Where(enemy => ((enemy.Position.X > center.X - viewSize.X / 2) && enemy.Position.X < center.X + viewSize.X / 2) && ((enemy.Position.Y > center.Y - viewSize.Y / 2) && (enemy.Position.Y < center.Y + viewSize.Y / 2))); var eneTmp = new List <Enemy>(EnemiesOnMap); //var eneTmpArr = eneTmp.ToArray(); foreach (var enemy in EnemiesRendered) { if (!shot.IsIntersecting(enemy.Position)) { continue; } tmp.Remove(shot); var enType = enemy.Type; if (WorldPlayer.EnemyICanAttack.Equals(enType) == false) { continue; } eneTmp.Remove(enemy); Score += enemy.TakeDownScore; } EnemiesOnMap = eneTmp; } WorldPlayer.ShotsFired = tmp; if (EnemiesOnMap.Count == 0) { continue; } { /* * Detect if the enemy is near an edge, if so then change its direction */ var center = _worldView.Center; var viewSize = _worldView.Size; EnemiesRendered = EnemiesOnMap.Where(enemy => ((enemy.Position.X >= center.X - viewSize.X / 2f) && enemy.Position.X <= center.X + viewSize.X / 2) && ((enemy.Position.Y >= center.Y - viewSize.Y / 2) && (enemy.Position.Y < center.Y - enemy.Height + viewSize.Y / 2))); foreach (var enemy in EnemiesRendered) { if (WorldPlayer.CanMove && !enemy.CanMove) { enemy.SetWaitToMax(); } var mapTiles = WorldMap.FloorObjects.Select(tiles => tiles.Position).Where(tile => tile.Y >= (enemy.Position.Y + enemy.Height)).ToList(); if (mapTiles != null && mapTiles.Count > 0) { var sortedTiles = SortByDistance(enemy.Position, mapTiles); var closetTilePos = sortedTiles[0]; var closestTile = WorldMap.FloorObjects.First(tile => tile.Position.Equals(closetTilePos)); if (bool.Parse(closestTile.Properties["leftNeighbor"]) == false) { enemy.IsNearEdge = true; enemy.TurnRight = true; enemy.TurnLeft = false; } else if (bool.Parse(closestTile.Properties["rightNeighbor"]) == false) { enemy.IsNearEdge = true; enemy.TurnRight = false; enemy.TurnLeft = true; } else { enemy.IsNearEdge = false; enemy.TurnRight = false; enemy.TurnLeft = false; } } // DictateSpriteFalling(enemy); if (WorldPlayer.IsIntersecting(enemy.Position)) { enemy.Attack(WorldPlayer); } var eneTmpShot = new List <Shot>(enemy.ShotsFired); var eneTmpShotArray = eneTmpShot.ToArray(); foreach (var shot in eneTmpShotArray) { var endOfScreen = _worldView.Center.X - shot.Width + _worldView.Size.X / 2.0f; if (shot.Position.X >= endOfScreen) { eneTmpShot.Remove(shot); continue; } if (shot.TotalTimeDrawn >= MaxTimeForBulletDraw) { eneTmpShot.Remove(shot); continue; } if (!shot.IsIntersecting(WorldPlayer.Position)) { continue; } WorldPlayer.Health -= enemy.AttackPower; eneTmpShot.Remove(shot); } enemy.ShotsFired = eneTmpShot; } } } } catch (ThreadAbortException) { LogManager.LogWarning("Aborting collision detection"); } finally { LogManager.LogWarning("Aborting collision detection"); } }