Beispiel #1
0
        /// <summary>
        /// gets a List of all the TiledTiles that intersect the passed in Rectangle. The returned List can be put back in the pool via ListPool.free.
        /// </summary>
        /// <returns>The tiles intersecting bounds.</returns>
        /// <param name="bounds">Bounds.</param>
        public new List <TiledTile> GetTilesIntersectingBounds(Rectangle bounds)
        {
            // Note that after transforming the bounds to isometric, top left is the left most tile, bottom right is the right most, top right is top most, bottom left is bottom most
            var topLeft     = TiledMap.IsometricWorldToTilePosition(bounds.X, bounds.Y);
            var bottomLeft  = TiledMap.IsometricWorldToTilePosition(bounds.X, bounds.Bottom);
            var topRight    = TiledMap.IsometricWorldToTilePosition(bounds.Right, bounds.Y);
            var bottomRight = TiledMap.IsometricWorldToTilePosition(bounds.Right, bounds.Bottom);

            var tilelist = ListPool <TiledTile> .Obtain();

            // Iterate in larger isometric rectangle that definitely includes our smaller bounding rectangle
            for (var x = topLeft.X; x <= bottomRight.X; x++)
            {
                for (var y = topRight.Y; y <= bottomLeft.Y; y++)
                {
                    var tile = GetTile(x, y);
                    // Check if tile collides with our bounds
                    if (tile != null && bounds.Contains(TiledMap.IsometricTileToWorldPosition(x, y)))
                    {
                        tilelist.Add(tile);
                    }
                }
            }

            return(tilelist);
        }
Beispiel #2
0
        public override void Draw(Batcher batcher, Vector2 position, float layerDepth, RectangleF cameraClipBounds)
        {
            // offset render position by the layer offset, used for isometric layer depth
            position += Offset;

            // offset it by the entity position since the tilemap will always expect positions in its own coordinate space
            cameraClipBounds.Location -= position;
            if (TiledMap.requiresLargeTileCulling)
            {
                // we expand our cameraClipBounds by the excess tile width/height of the largest tiles to ensure we include tiles whose
                // origin might be outside of the cameraClipBounds
                cameraClipBounds.Location -= new Vector2(TiledMap.LargestTileWidth,
                                                         TiledMap.LargestTileHeight - TiledMap.TileHeight);
                cameraClipBounds.Size += new Vector2(TiledMap.LargestTileWidth,
                                                     TiledMap.LargestTileHeight - TiledMap.TileHeight);
            }

            Point min, max;

            min = new Point(0, 0);
            max = new Point(TiledMap.Width - 1, TiledMap.Height - 1);

            // loop through and draw all the non-culled tiles
            for (var y = min.Y; y <= max.Y; y++)
            {
                for (var x = min.X; x <= max.X; x++)
                {
                    var tile = GetTile(x, y);
                    if (tile == null)
                    {
                        continue;
                    }

                    var tileworldpos = TiledMap.IsometricTileToWorldPosition(x, y);
                    if (tileworldpos.X < cameraClipBounds.Left || tileworldpos.Y < cameraClipBounds.Top ||
                        tileworldpos.X > cameraClipBounds.Right || tileworldpos.Y > cameraClipBounds.Bottom)
                    {
                        continue;
                    }

                    var tileRegion = tile.TextureRegion;

                    // culling for arbitrary size tiles if necessary
                    if (TiledMap.requiresLargeTileCulling)
                    {
                        // TODO: this only checks left and bottom. we should check top and right as well to deal with rotated, odd-sized tiles
                        if (tileworldpos.X + tileRegion.SourceRect.Width < cameraClipBounds.Left ||
                            tileworldpos.Y - tileRegion.SourceRect.Height > cameraClipBounds.Bottom)
                        {
                            continue;
                        }
                    }

                    DrawTile(batcher, position, layerDepth, x, y, 1);
                }
            }
        }
Beispiel #3
0
        public void DrawTile(Batcher batcher, Vector2 position, float layerDepth, int x, int y, float scale)
        {
            var tile = GetTile(x, y);

            if (tile == null)
            {
                return;
            }

            var t          = TiledMap.IsometricTileToWorldPosition(x, y);
            var tileRegion = tile.TextureRegion;

            // for the y position, we need to take into account if the tile is larger than the tileHeight and shift. Tiled uses
            // a bottom-left coordinate system and MonoGame a top-left
            var rotation = 0f;

            var spriteEffects = SpriteEffects.None;

            if (tile.FlippedHorizonally)
            {
                spriteEffects |= SpriteEffects.FlipHorizontally;
            }
            if (tile.FlippedVertically)
            {
                spriteEffects |= SpriteEffects.FlipVertically;
            }
            if (tile.FlippedDiagonally)
            {
                if (tile.FlippedHorizonally && tile.FlippedVertically)
                {
                    spriteEffects ^= SpriteEffects.FlipVertically;
                    rotation       = MathHelper.PiOver2;
                    t.X           += TiledMap.TileHeight + (tileRegion.SourceRect.Height - TiledMap.TileHeight);
                    t.Y           -= (tileRegion.SourceRect.Width - TiledMap.TileWidth);
                }
                else if (tile.FlippedHorizonally)
                {
                    spriteEffects ^= SpriteEffects.FlipVertically;
                    rotation       = -MathHelper.PiOver2;
                    t.Y           += TiledMap.TileHeight;
                }
                else if (tile.FlippedVertically)
                {
                    spriteEffects ^= SpriteEffects.FlipHorizontally;
                    rotation       = MathHelper.PiOver2;
                    t.X           += TiledMap.TileWidth + (tileRegion.SourceRect.Height - TiledMap.TileHeight);
                    t.Y           += (TiledMap.TileWidth - tileRegion.SourceRect.Width);
                }
                else
                {
                    spriteEffects ^= SpriteEffects.FlipHorizontally;
                    rotation       = -MathHelper.PiOver2;
                    t.Y           += TiledMap.TileHeight;
                }
            }

            // if we had no rotations (diagonal flipping) shift our y-coord to account for any non-tileSized tiles to account for
            // Tiled being bottom-left origin
            if (rotation == 0)
            {
                t.Y += (TiledMap.TileHeight - tileRegion.SourceRect.Height);
            }

            // Scale the tile's relative position, but not the origin
            t = t * new Vector2(scale) + position;

            batcher.Draw(tileRegion.Texture2D, t, tileRegion.SourceRect, Color, rotation, Vector2.Zero, scale, spriteEffects, layerDepth);
        }