예제 #1
0
        // overlapsWithCallBack
        public Boolean overlapsWithCallback(FlxObject Object, Func <FlxObject, FlxObject, Boolean> Callback = null, Boolean FlipCallbackParams = false, FlxPoint Position = null)
        {
            Boolean results = false;

            float X = base.X;
            float Y = base.Y;

            if (Position != null)
            {
                X = Position.X;
                Y = Position.X;
            }

            //Figure out what tiles we need to check against
            int  selectionX      = (int)FlxU.floor((Object.X - X) / _tileWidth);
            int  selectionY      = (int)FlxU.floor((Object.Y - Y) / _tileHeight);
            uint selectionWidth  = (uint)(selectionX + (FlxU.ceil((int)Object.Width / _tileWidth)) + 2);
            uint selectionHeight = (uint)(selectionY + (FlxU.ceil((int)Object.Height / _tileHeight)) + 2);

            //Then bound these coordinates by the map edges
            if (selectionX < 0)
            {
                selectionX = 0;
            }
            if (selectionY < 0)
            {
                selectionY = 0;
            }
            if (selectionWidth > widthInTiles)
            {
                selectionWidth = (uint)widthInTiles;
            }
            if (selectionHeight > heightInTiles)
            {
                selectionHeight = (uint)heightInTiles;
            }

            //Then loop through this selection of tiles and call FlxObject.separate() accordingly
            uint    rowStart = (uint)selectionY * (uint)widthInTiles;
            uint    row      = (uint)selectionY;
            uint    column;
            FlxTile tile;
            Boolean overlapFound;
            float   deltaX = X - Last.X;
            float   deltaY = Y - Last.Y;



            while (row < selectionHeight)
            {
                column = (uint)selectionX;
                while (column < selectionWidth)
                {
                    overlapFound = false;
                    tile         = _tileObjects[(int)_data[(int)(rowStart + column)]] as FlxTile;
                    if (Convert.ToBoolean(tile.AllowCollisions))
                    {
                        tile.X      = X + (int)column * _tileWidth;
                        tile.Y      = Y + (int)row * _tileHeight;
                        tile.Last.X = tile.X - deltaX;
                        tile.Last.Y = tile.Y - deltaY;
                        if (Callback != null)
                        {
                            if (FlipCallbackParams)
                            {
                                overlapFound = Callback(Object, tile);
                            }
                            else
                            {
                                overlapFound = Callback(tile, Object);
                            }
                        }
                        else
                        {
                            overlapFound = (Object.X + Object.Width > tile.X) && (Object.X < tile.X + tile.Width) && (Object.Y + Object.Height > tile.Y) && (Object.Y < tile.Y + tile.Height);
                        }
                        if (overlapFound)
                        {
                            if ((tile.callback != null))
                            {
                                tile.mapIndex = (uint)rowStart + column;
                                tile.callback(tile, Object);
                            }
                            results = true;
                        }
                    }
                    else if ((tile.callback != null))
                    {
                        tile.mapIndex = (uint)rowStart + (uint)column;
                        tile.callback(tile, Object);
                    }
                    column++;
                }
                rowStart += (uint)widthInTiles;
                row++;
            }
            return(results);
        }
예제 #2
0
        /**
         * Shoots a ray from the start point to the end point.
         * If/when it passes through a tile, it stores that point and returns false.
         *
         * @param	Start		The world coordinates of the start of the ray.
         * @param	End			The world coordinates of the end of the ray.
         * @param	Result		A <code>Point</code> object containing the first wall impact.
         * @param	Resolution	Defaults to 1, meaning check every tile or so.  Higher means more checks!
         * @return	Returns true if the ray made it from Start to End without hitting anything.  Returns false and fills Result if a tile was hit.
         */
        public bool ray(FlxPoint Start, FlxPoint End, FlxPoint Result = null, float Resolution = 1f)
        {
            float step = _tileWidth;

            if (_tileHeight < _tileWidth)
            {
                step = _tileHeight;
            }
            step /= Resolution;
            float deltaX   = End.X - Start.X;
            float deltaY   = End.Y - Start.Y;
            float distance = (float)Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
            int   steps    = (int)FlxU.ceil(distance / step);
            float stepX    = deltaX / steps;
            float stepY    = deltaY / steps;
            float curX     = Start.X - stepX - X;
            float curY     = Start.Y - stepY - Y;
            int   tileX;
            int   tileY;
            int   i = 0;

            while (i < steps)
            {
                curX += stepX;
                curY += stepY;

                if ((curX < 0) || (curX > Width) || (curY < 0) || (curY > Height))
                {
                    i++;
                    continue;
                }

                tileX = (int)curX / _tileWidth;
                tileY = (int)curY / _tileHeight;
                if (Convert.ToBoolean((_tileObjects[_data[tileY * widthInTiles + tileX]] as FlxTile).AllowCollisions))
                {
                    //Some basic helper stuff
                    tileX *= _tileWidth;
                    tileY *= _tileHeight;
                    float rx = 0;
                    float ry = 0;
                    float q;
                    float lx = curX - stepX;
                    float ly = curY - stepY;

                    //Figure out if it crosses the X boundary
                    q = tileX;
                    if (deltaX < 0)
                    {
                        q += _tileWidth;
                    }
                    rx = q;
                    ry = ly + stepY * ((q - lx) / stepX);
                    if ((ry > tileY) && (ry < tileY + _tileHeight))
                    {
                        if (Result == null)
                        {
                            Result = new FlxPoint();
                        }
                        Result.X = rx;
                        Result.Y = ry;
                        return(false);
                    }

                    //Else, figure out if it crosses the Y boundary
                    q = tileY;
                    if (deltaY < 0)
                    {
                        q += _tileHeight;
                    }
                    rx = lx + stepX * ((q - ly) / stepY);
                    ry = q;
                    if ((rx > tileX) && (rx < tileX + _tileWidth))
                    {
                        if (Result == null)
                        {
                            Result = new FlxPoint();
                        }
                        Result.X = rx;
                        Result.Y = ry;
                        return(false);
                    }
                    return(true);
                }
                i++;
            }
            return(true);
        }