private static void DrawTilesInTileLayer(Graphics g, TmxMap tmxMap, TmxLayer layer) { // Set the opacity for the layer (Not supported on Mac builds) #if !TILED2UNITY_MAC ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.Matrix33 = layer.Opacity; ImageAttributes imageAttributes = new ImageAttributes(); imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap); #endif // 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 (tmxMap.DrawOrderHorizontal == -1) { range_x = range_x.Reverse(); } if (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 = tmxMap.Tiles[tileId] // Support for animated tiles. Just show the first frame of the animation. let frame = tmxMap.Tiles[tile.Animation.Frames[0].GlobalTileId] select new { Tile = frame, Position = TmxMath.TileCornerInScreenCoordinates(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) + 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); #if !TILED2UNITY_MAC g.DrawImage(t.Bitmap, destPoints3, source, GraphicsUnit.Pixel, imageAttributes); #else g.DrawImage(t.Bitmap, destPoints3, source, GraphicsUnit.Pixel); #endif } }