public void Start() { //add players to the game if (UserControlledPlayers.Count > 0) { GameElements.AddRange(UserControlledPlayers); } if (InitialBots.Count > 0) { GameElements.AddRange(InitialBots); } //start the Renderer to draw all elements on the screen //Render.Start(); //moved inside Logic Loop to show objective and players //we want to be able to cancel the Task therefore we need a Cancellation-Token GameLoopTokenSource = new CancellationTokenSource(); GameLoopCancellationToken = GameLoopTokenSource.Token; //Start the Logic Loop Task.Run(() => { GameObject CurrentPickup; int RespawnCounter = RespawnCounterSave; int PickupCounter = PickupCounterSave; int RespawnTeam = 1; Stopwatch stopper = new Stopwatch(); List <int> IndicesToRemove = new List <int>(); List <int> BulletIndicesToRemove = new List <int>(); List <int> PickupIndicesToRemove = new List <int>(); Team WinningTeam = null; Render.ShowStartConfig(); if (UserControlledPlayers.Count > 0) { Render.ShowFindPlayerDialog(); for (int i = 0; i < 300; i++) { if (Escape_Current_Intro) { Escape_Current_Intro = false; break; } else { Thread.Sleep(10); } } Render.HighlightPlayers(); for (int i = 0; i < 300; i++) { if (Escape_Current_Intro) { Escape_Current_Intro = false; break; } else { Thread.Sleep(10); } } } Render.ShowPlaymodeObjective(); for (int i = 0; i < 300; i++) { if (Escape_Current_Intro) { Escape_Current_Intro = false; break; } else { Thread.Sleep(10); } } for (int i = 5; i > 0; i--) { Render.ShowCountdownNumber(i); for (int j = 0; j < 100; j++) { if (Escape_Current_Intro) { Escape_Current_Intro = false; break; } else { Thread.Sleep(10); } } } Render.Start(); //The never-ending game loop while (true) { //check if our Task is canceled from outside if (GameLoopCancellationToken.IsCancellationRequested) { //if our Task was cancelled, end the loop break; } IndicesToRemove.Clear(); BulletIndicesToRemove.Clear(); PickupIndicesToRemove.Clear(); stopper.Start(); lock (GameElementListLock) for (int i = 0; i < GameElements.Count; i++) { GameElements[i].move(); if (GameElements[i].IsDead) { IndicesToRemove.Add(i); } } lock (BulletListLock) for (int i = 0; i < BulletElements.Count; i++) { BulletElements[i].move(); if (BulletElements[i].IsDead) { BulletIndicesToRemove.Add(i); } } lock (PickupListLock) for (int i = 0; i < PickupElements.Count; i++) { PickupElements[i].move(); if (PickupElements[i].IsDead) { PickupIndicesToRemove.Add(i); } } //IndicesToRemove = IndicesToRemove.OrderBy(x => x).ToList(); lock (GameElementListLock) for (int i = 0; i < IndicesToRemove.Count; i++) { GameElements.RemoveAt(IndicesToRemove[i] - i); } lock (BulletListLock) for (int i = 0; i < BulletIndicesToRemove.Count; i++) { BulletElements.RemoveAt(BulletIndicesToRemove[i] - i); } lock (PickupListLock) for (int i = 0; i < PickupIndicesToRemove.Count; i++) { PickupElements.RemoveAt(PickupIndicesToRemove[i] - i); } //Respawn if (RespawnCounter-- < 0) { RespawnCounter = RespawnCounterSave; lock (GameElementListLock) GameElements.Add(new Fighter(Lucky.Next(50, Width - 50), Lucky.Next(50, Height - 50), Teams[(RespawnTeam++ % Teams.Count)], this)); } //PickUps if (PickupCounter-- < 0) { PickupCounter = PickupCounterSave; CurrentPickup = PickupManager.SpawnRandomPickUp(); if (CurrentPickup != null) { lock (PickupListLock) PickupElements.Add((PickUp)CurrentPickup); } } //Special events from game mode PlayMode.SpecialEvent(); if (this.PlayMode.checkWin(out WinningTeam)) { GameOver(WinningTeam); } stopper.Stop(); if (stopper.ElapsedMilliseconds < LogicTime) { Thread.Sleep((int)(LogicTime - stopper.ElapsedMilliseconds)); } //to show Logic FPS in game LogicTimeActual = stopper.ElapsedMilliseconds; stopper.Reset(); } }); }