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();
        }
Exemple #2
0
        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);
            }
        }