/// <summary> /// Thread body which performs one game loop step and renders map to buffer. /// </summary> private void PerformGameLoopStep(object sender, EventArgs e) { // game loop steps per second double gsps = 10; // milliseconds per game loop step double mspgs = 1000.0 / gsps; // last time game loop step was performed double lastTime = lastTimeGameLoopStep; GameViewModel gameView = viewModel; //current time double currentTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond; // lock game view, perform game loop step and pass task with data context update if ((currentTime - lastTime) >= mspgs) { while (!Monitor.TryEnter(gameView)) { Thread.Sleep(100); } try { gameView.GameLoopStep(); } catch (Exception ex) { // todo: something } bool winner = gameView.GameInstance.IsWinner; if (gameView.GameInstance.IsWinner) { ((DispatcherTimer)sender).Stop(); viewModel.AddGameMessage($"Player {gameView.GameInstance.Winner.Name} has won!"); } lastTimeGameLoopStep = currentTime; Application.Current.Dispatcher.Invoke(() => { viewModel = gameView; DataContext = viewModel; gameView.NotifyPropertyChanges(); if (winner) { OnGameEnded(); } }); Monitor.Exit(gameView); } }