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 } }
private static void DrawTilesInTileLayer(SKCanvas canvas, TmxMap tmxMap, TmxLayer layer) { using (SKPaint paint = new SKPaint()) { // Set the opacity for the layer paint.Color = SKColors.White.WithAlpha((byte)(layer.Opacity * byte.MaxValue)); // 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 = tmxMap.GetMapPositionAt(x, y, frame), Bitmap = frame.TmxImage.ImageBitmap, IsFlippedDiagnoally = TmxMath.IsTileFlippedDiagonally(rawTileId), IsFlippedHorizontally = TmxMath.IsTileFlippedHorizontally(rawTileId), IsFlippedVertically = TmxMath.IsTileFlippedVertically(rawTileId), }; foreach (var t in tiles) { PointF location = t.Position; using (new SKAutoCanvasRestore(canvas)) { bool flip_h = t.IsFlippedHorizontally; bool flip_v = t.IsFlippedVertically; bool flip_d = t.IsFlippedDiagnoally; // Move to the center of the tile on location and perform and transforms SKPoint center = new SKPoint(t.Tile.TileSize.Width * 0.5f, t.Tile.TileSize.Height * 0.5f); canvas.Translate(center.X, center.Y); canvas.Translate(location.X, location.Y); // Flip transformations (logic taken from Tiled source: maprenderer.cpp) { // If we're flipping diagonally then rotate 90 degrees and reverse h/v flip flags float rotate = 0; if (flip_d) { rotate = 90; flip_h = t.IsFlippedVertically; flip_v = !t.IsFlippedHorizontally; } // Scale based on flip flags float scale_x = flip_h ? -1.0f : 1.0f; float scale_y = flip_v ? -1.0f : 1.0f; canvas.Scale(scale_x, scale_y); canvas.RotateDegrees(rotate); } // Move us back out of the center canvas.Translate(-center.X, -center.Y); // Draw the tile SKRect dest = SKRect.Create(0, 0, t.Tile.TileSize.Width, t.Tile.TileSize.Height); SKRect source = SKRect.Create(t.Tile.LocationOnSource.X, t.Tile.LocationOnSource.Y, t.Tile.TileSize.Width, t.Tile.TileSize.Height); canvas.DrawBitmap(t.Bitmap, source, dest, paint); } } } }