/// <summary> /// Configures the render context for drawing the specified layer. /// </summary> /// <param name="layer">The layer.</param> private void ConfigureContextForLayer(GeometryTileLayer layer) { if (layer == null) { throw new ArgumentNullException(nameof(layer)); } var map = _mapService.CurrentMap; /* * Get the number of map tiles each layer tile covers. * This is becasue the map layers may use tiles which are larger * than the map tiles, map tiles are usually 16x16, but layers * can have tiles up to 128x128. * * If we don't take this into account the rendering will clip * tiles larger than 16x16 at the wrong time, causing them to * "pop" in and out as the player moves. */ var widthMultiplier = (layer.MaxTileWidth / map.GeometryTileWidth); var heightMultiplier = (layer.MaxTileHeight / map.GeometryTileHeight); // get the width and height of each tile to be rendered _rc.RenderTileWidth = map.GeometryTileWidth; _rc.RenderTileHeight = map.GeometryTileHeight; // maximum number of tiles we will render _rc.TilesWide = (int)Math.Ceiling((double)_width / map.GeometryTileWidth) + 1; _rc.TilesHigh = (int)Math.Ceiling((double)_height / map.GeometryTileHeight) + 1; _rc.TilesWide *= widthMultiplier; _rc.TilesHigh *= heightMultiplier; // actual x/y render start point - may be slightly beyond screen bounds var x = (Camera.Position.X * layer.HorizontalScrollMultipler) + layer.HorizontalOffset; var y = (Camera.Position.Y * layer.VerticalScrollMultipler) + layer.VerticalOffset; _rc.Origin = new Int32Point((int)x, (int)y); // determine the leftmost and topmost boundaries we will be drawing _rc.LeftBound = _rc.Origin.X - (_width / 2); _rc.TopBound = _rc.Origin.Y - (_height / 2); // determine the row and column of the leftmost and topmost tiles we will be drawing _rc.FirstTileCol = _rc.LeftBound / _rc.RenderTileWidth - widthMultiplier; _rc.FirstTileRow = _rc.TopBound / _rc.RenderTileHeight - heightMultiplier; // clamp _rc.FirstTileCol = Math.Max(0, _rc.FirstTileCol); _rc.FirstTileRow = Math.Max(0, _rc.FirstTileRow); }
/// <summary> /// Processes the geometry layer, creating the game representation. /// </summary> /// <param name="rawLayer">The layer.</param> /// <param name="map">The map.</param> /// <param name="tileDefinitions">A global dictionary of all tile definitions.</param> /// <returns> /// An instance of a new <see cref="GeometryTileLayer" />. /// </returns> private void ProcessGeometryLayer(TmxLayer rawLayer, GeometryTileLayer layer, Map map, IDictionary <int, TileDefinition> tileDefinitions) { if (rawLayer == null) { throw new ArgumentNullException(nameof(rawLayer)); } if (layer == null) { throw new ArgumentNullException(nameof(layer)); } if (map == null) { throw new ArgumentNullException(nameof(map)); } if (tileDefinitions == null) { throw new ArgumentNullException(nameof(tileDefinitions)); } TraceSource.TraceEvent(TraceEventType.Verbose, 0, $"Processing layer {rawLayer.Name}"); var tiles = new List <GeometryTile>(); foreach (var tile in rawLayer.Tiles) { if (tile.Gid != 0) { var geoTile = new GeometryTile(); geoTile.GridPosition = new Int32Point(tile.X, tile.Y); geoTile.WorldPosition = new Int32Point(tile.X * map.GeometryTileWidth, tile.Y * map.GeometryTileHeight); geoTile.Definition = tileDefinitions[tile.Gid]; geoTile.DefinitionId = tile.Gid; tiles.Add(geoTile); } } layer.SetTiles(tiles); }