public async Task UpdateViewAsync(Engine engine, EngineInput input, CancellationToken token) { // Re-sync the screen bool forceRefresh = await SyncScreenDimensionsAsync() || input == EngineInput.RefreshView; // Process input to re-center map switch (input) { case EngineInput.ModifiedDirectionUp: case EngineInput.ModifiedDirectionUpRight: case EngineInput.ModifiedDirectionRight: case EngineInput.ModifiedDirectionDownRight: case EngineInput.ModifiedDirectionDown: case EngineInput.ModifiedDirectionDownLeft: case EngineInput.ModifiedDirectionLeft: case EngineInput.ModifiedDirectionUpLeft: MoveMapCamera((Direction)((int)input - (int)EngineInput.ModifiedDirectionUp)); break; case EngineInput.ModifiedDirectionCenter: CenterMapCamera(engine.Game.Player.X, engine.Game.Player.Y); break; } // Move camera to keep player on screen var playerBounds = MapWindow.Shift(MapCameraXOffset, MapCameraYOffset).ResizeFromCenter(-1); if (playerBounds.GetRectPart(engine.Game.Player.X, engine.Game.Player.Y) != RectPart.Inside) { // TODO: Centering on player is aggressive but fine for now, replace with smoother pan CenterMapCamera(engine.Game.Player.X, engine.Game.Player.Y); } if (forceRefresh) { await ClearScreenAsync(); } foreach ((int screenX, int screenY) in GetScreenCoordinatesEnumerable()) { T?oldTile = TileBuffer[screenX, screenY]; T?newTile = null; if (MapWindow.Contains(screenX, screenY)) { // Get map tile int mapX = screenX - MapWindow.X + MapCameraXOffset; int mapY = screenY - MapWindow.Y + MapCameraYOffset; newTile = engine.Game.WorldMap.Contains(mapX, mapY) ? GetMapTile(engine.Game.WorldMap[mapX, mapY], engine.Game.Creatures[mapX, mapY]?.Type) : null; } if (forceRefresh || (oldTile is not null && !oldTile.Equals(newTile)) || (newTile is not null && !newTile.Equals(oldTile))) { TileBuffer[screenX, screenY] = newTile; await DrawScreenTileAsync(screenX, screenY); } } }