private void DrawTiles(Graphics g) { // Load all our tiled images var images = from layer in this.tmxMap.Layers where layer.Properties.GetPropertyValueAsBoolean("unity:collisionOnly", false) == false where layer.Visible == true where IsLayerEnabled(layer.DefaultName) from y in Enumerable.Range(0, layer.Height) from x in Enumerable.Range(0, layer.Width) let tileId = layer.GetTileIdAt(x, y) where tileId != 0 let tile = this.tmxMap.Tiles[tileId] select new { Path = tile.TmxImage.Path, Trans = tile.TmxImage.TransparentColor, }; images = images.Distinct(); Dictionary <string, Bitmap> tileSetBitmaps = new Dictionary <string, Bitmap>(); foreach (var img in images) { Bitmap bmp = (Bitmap)Bitmap.FromFile(img.Path); if (!String.IsNullOrEmpty(img.Trans)) { System.Drawing.Color transColor = System.Drawing.ColorTranslator.FromHtml(img.Trans); bmp.MakeTransparent(transColor); } tileSetBitmaps.Add(img.Path, bmp); } foreach (TmxLayer layer in this.tmxMap.Layers) { if (layer.Visible == false) { continue; } if (IsLayerEnabled(layer.DefaultName) == false) { continue; } if (layer.Properties.GetPropertyValueAsBoolean("unity:collisionOnly", false) == true) { continue; } // The range of x and y depends on the render order of the tiles // By default we draw right and down but may reverse the tiles we visit var range_x = Enumerable.Range(0, layer.Width); var range_y = Enumerable.Range(0, layer.Height); if (this.tmxMap.DrawOrderHorizontal == -1) { range_x = range_x.Reverse(); } if (this.tmxMap.DrawOrderVertical == -1) { range_y = range_y.Reverse(); } // Visit the tiles we are going to draw var tiles = from y in range_y from x in range_x let rawTileId = layer.GetRawTileIdAt(x, y) let tileId = layer.GetTileIdAt(x, y) where tileId != 0 let tile = this.tmxMap.Tiles[tileId] // Support for animated tiles. Just show the first frame of the animation. let frame = (tile.Animation == null) ? tile : this.tmxMap.Tiles[tile.Animation.Frames[0].GlobalTileId] select new { Tile = frame, Position = TmxMath.TileCornerInScreenCoordinates(this.tmxMap, x, y), Bitmap = tileSetBitmaps[frame.TmxImage.Path], IsFlippedDiagnoally = TmxMath.IsTileFlippedDiagonally(rawTileId), IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId), IsFlippedVertically = TmxMath.IsTileFlippedVertically(rawTileId), }; PointF[] destPoints = new PointF[4]; PointF[] destPoints3 = new PointF[3]; foreach (var t in tiles) { PointF location = t.Position; // Individual tiles may be larger than the given tile size of the overall map location.Y = (t.Position.Y - t.Tile.TileSize.Height) + this.tmxMap.TileHeight; // Make up the 'quad' of texture points and transform them PointF center = new PointF(t.Tile.TileSize.Width * 0.5f, t.Tile.TileSize.Height * 0.5f); destPoints[0] = new Point(0, 0); destPoints[1] = new Point(t.Tile.TileSize.Width, 0); destPoints[2] = new Point(t.Tile.TileSize.Width, t.Tile.TileSize.Height); destPoints[3] = new Point(0, t.Tile.TileSize.Height); // Transform the points based on our flipped flags TmxMath.TransformPoints(destPoints, center, t.IsFlippedDiagnoally, t.IsFlippedHorizontally, t.IsFlippedVertically); // Put the destination points back into world space TmxMath.TranslatePoints(destPoints, location); // Stupid DrawImage function only takes 3 destination points otherwise it throws an exception destPoints3[0] = destPoints[0]; destPoints3[1] = destPoints[1]; destPoints3[2] = destPoints[3]; // Draw the tile Rectangle source = new Rectangle(t.Tile.LocationOnSource, t.Tile.TileSize); g.DrawImage(t.Bitmap, destPoints3, source, GraphicsUnit.Pixel); } } tileSetBitmaps.Clear(); }
private void DrawTiles(Graphics g) { foreach (TmxLayer layer in this.tmxMap.Layers) { if (layer.Visible == false) { continue; } if (layer.Ignore == TmxLayer.IgnoreSettings.Visual) { continue; } // Set the opacity for the layer ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix33 = layer.Opacity; ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); // Translate by the offset GraphicsState state = g.Save(); g.TranslateTransform(layer.Offset.X, layer.Offset.Y); // The range of x and y depends on the render order of the tiles // By default we draw right and down but may reverse the tiles we visit var range_x = Enumerable.Range(0, GetMaxTilesWide(layer)); var range_y = Enumerable.Range(0, GetMaxTilesHigh(layer)); if (this.tmxMap.DrawOrderHorizontal == -1) { range_x = range_x.Reverse(); } if (this.tmxMap.DrawOrderVertical == -1) { range_y = range_y.Reverse(); } // Visit the tiles we are going to draw var tiles = from y in range_y from x in range_x let rawTileId = layer.GetRawTileIdAt(x, y) let tileId = layer.GetTileIdAt(x, y) where tileId != 0 let tile = this.tmxMap.Tiles[tileId] // Support for animated tiles. Just show the first frame of the animation. let frame = this.tmxMap.Tiles[tile.Animation.Frames[0].GlobalTileId] select new { Tile = frame, Position = TmxMath.TileCornerInScreenCoordinates(this.tmxMap, x, y), Bitmap = frame.TmxImage.ImageBitmap, IsFlippedDiagnoally = TmxMath.IsTileFlippedDiagonally(rawTileId), IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId), IsFlippedVertically = TmxMath.IsTileFlippedVertically(rawTileId), }; PointF[] destPoints = new PointF[4]; PointF[] destPoints3 = new PointF[3]; foreach (var t in tiles) { PointF location = t.Position; // Individual tiles may be larger than the given tile size of the overall map location.Y = (t.Position.Y - t.Tile.TileSize.Height) + this.tmxMap.TileHeight; // Take tile offset into account location.X += t.Tile.Offset.X; location.Y += t.Tile.Offset.Y; // Make up the 'quad' of texture points and transform them PointF center = new PointF(t.Tile.TileSize.Width * 0.5f, t.Tile.TileSize.Height * 0.5f); destPoints[0] = new Point(0, 0); destPoints[1] = new Point(t.Tile.TileSize.Width, 0); destPoints[2] = new Point(t.Tile.TileSize.Width, t.Tile.TileSize.Height); destPoints[3] = new Point(0, t.Tile.TileSize.Height); // Transform the points based on our flipped flags TmxMath.TransformPoints(destPoints, center, t.IsFlippedDiagnoally, t.IsFlippedHorizontally, t.IsFlippedVertically); // Put the destination points back into world space TmxMath.TranslatePoints(destPoints, location); // Stupid DrawImage function only takes 3 destination points otherwise it throws an exception destPoints3[0] = destPoints[0]; destPoints3[1] = destPoints[1]; destPoints3[2] = destPoints[3]; // Draw the tile Rectangle source = new Rectangle(t.Tile.LocationOnSource, t.Tile.TileSize); g.DrawImage(t.Bitmap, destPoints3, source, GraphicsUnit.Pixel, imageAttributes); } g.Restore(state); } }