Exemple #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);
        }
Exemple #2
0
        /// <summary>
        /// casts a line from start to end returning the first solid tile it intersects. Note that start and end and clamped to the tilemap
        /// bounds so make sure you pass in valid positions else you may get odd results!
        /// </summary>
        /// <param name="start">Start.</param>
        /// <param name="end">End.</param>
        public new TiledTile Linecast(Vector2 start, Vector2 end)
        {
            var direction = end - start;

            // worldToTilePosition clamps to the tilemaps bounds so no need to worry about overlow
            var startCell = TiledMap.IsometricWorldToTilePosition(start);
            var endCell   = TiledMap.IsometricWorldToTilePosition(end);

            start.X /= TiledMap.TileWidth;
            start.Y /= TiledMap.TileHeight;

            // what tile are we on
            var intX = startCell.X;
            var intY = startCell.Y;

            // ensure our start cell exists
            if (intX < 0 || intX >= TiledMap.Width || intY < 0 || intY >= TiledMap.Height)
            {
                return(null);
            }

            // which way we go
            var stepX = Math.Sign(direction.X);
            var stepY = Math.Sign(direction.Y);

            // Calculate cell boundaries. when the step is positive, the next cell is after this one meaning we add 1.
            // If negative, cell is before this one in which case dont add to boundary
            var boundaryX = intX + (stepX > 0 ? 1 : 0);
            var boundaryY = intY + (stepY > 0 ? 1 : 0);

            // determine the value of t at which the ray crosses the first vertical tile boundary. same for y/horizontal.
            // The minimum of these two values will indicate how much we can travel along the ray and still remain in the current tile
            // may be infinite for near vertical/horizontal rays
            var tMaxX = (boundaryX - start.X) / direction.X;
            var tMaxY = (boundaryY - start.Y) / direction.Y;

            if (direction.X == 0f)
            {
                tMaxX = float.PositiveInfinity;
            }
            if (direction.Y == 0f)
            {
                tMaxY = float.PositiveInfinity;
            }

            // how far do we have to walk before crossing a cell from a cell boundary. may be infinite for near vertical/horizontal rays
            var tDeltaX = stepX / direction.X;
            var tDeltaY = stepY / direction.Y;

            // start walking and returning the intersecting tiles
            var tile = Tiles[intX + intY * Width];

            if (tile != null)
            {
                return(tile);
            }

            while (intX != endCell.X || intY != endCell.Y)
            {
                if (tMaxX < tMaxY)
                {
                    intX  += stepX;
                    tMaxX += tDeltaX;
                }
                else
                {
                    intY  += stepY;
                    tMaxY += tDeltaY;
                }

                tile = Tiles[intX + intY * Width];
                if (tile != null)
                {
                    return(tile);
                }
            }

            return(null);
        }
Exemple #3
0
        /// <summary>
        /// note that world position assumes that the Vector2 was normalized to be in the tilemaps coordinates. i.e. if the tilemap
        /// is not at 0,0 then the world position should be moved so that it takes into consideration the tilemap offset from 0,0.
        /// Example: if the tilemap is at 300,300 then the passed in value should be worldPos - (300,300)
        /// </summary>
        /// <returns>The tile at world position.</returns>
        /// <param name="pos">Position.</param>
        public new TiledTile GetTileAtWorldPosition(Vector2 pos)
        {
            var tilePos = TiledMap.IsometricWorldToTilePosition(pos);

            return(GetTile(tilePos.X, tilePos.Y));
        }