Пример #1
0
        /// <summary>
        /// Checks for overlaps between the provided object and any tiles above the collision index.
        /// </summary>
        /// <param name="Core">The <code>FlxObject</code> you want to check against.</param>
        /// <returns>True if overlap occurs, otherwise False</returns>
        override public bool overlaps(FlxObject Core)
        {
            int d;

            int dd;
            List <BlockPoint> blocks = new List <BlockPoint>();

            //First make a list of all the blocks we'll use for collision
            int ix = (int)FlxU.floor((Core.x - x) / _tileWidth);
            int iy = (int)FlxU.floor((Core.y - y) / _tileHeight);
            int iw = (int)FlxU.ceil((float)Core.width / (float)_tileWidth) + 1;
            int ih = (int)FlxU.ceil((float)Core.height / (float)_tileHeight) + 1;
            int r  = 0;
            int c;

            while (r < ih)
            {
                if (r >= heightInTiles)
                {
                    break;
                }
                d = (iy + r) * widthInTiles + ix;
                c = 0;
                while (c < iw)
                {
                    if (c >= widthInTiles)
                    {
                        break;
                    }
                    dd = _data[d + c];
                    if (dd >= collideMin && dd >= collideMax)
                    {
                        blocks.Add(new BlockPoint((int)(x + (ix + c) * _tileWidth), (int)(y + (iy + r) * _tileHeight), dd));
                    }
                    c++;
                }
                r++;
            }

            //Then check for overlaps
            int bl = blocks.Count;
            int i  = 0;

            while (i < bl)
            {
                _block.x = blocks[i].x;
                _block.y = blocks[i++].y;
                if (_block.overlaps(Core))
                {
                    return(true);
                }
            }
            return(false);
        }
Пример #2
0
        /// <summary>
        /// <code>FlxU.collide()</code> (and thus <code>FlxObject.collide()</code>) call
        /// this function each time two objects are compared to see if they collide.
        /// It doesn't necessarily mean these objects WILL collide, however.
        /// </summary>
        /// <param name="Object">The <code>FlxObject</code> you're about to run into.</param>
        override public void preCollide(FlxObject Object)
        {
            //Collision fix, in case updateMotion() is called
            colHullX.x = 0;
            colHullX.y = 0;
            colHullY.x = 0;
            colHullY.y = 0;

            int r;
            int c;
            int rs;
            int ix = (int)FlxU.floor((Object.x - x) / _tileWidth);
            int iy = (int)FlxU.floor((Object.y - y) / _tileHeight);
            int iw = ix + (int)FlxU.ceil((float)Object.width / (float)_tileWidth) + 1;
            int ih = iy + (int)FlxU.ceil((float)Object.height / (float)_tileHeight) + 1;

            if (ix < 0)
            {
                ix = 0;
            }
            if (iy < 0)
            {
                iy = 0;
            }
            if (iw > widthInTiles)
            {
                iw = widthInTiles;
            }
            if (ih > heightInTiles)
            {
                ih = heightInTiles;
            }
            rs = iy * widthInTiles;
            r  = iy;
            colOffsets.Clear();
            while (r < ih)
            {
                c = ix;
                while (c < iw)
                {
                    if (_data[rs + c] >= collideMin && _data[rs + c] <= collideMax)
                    {
                        colOffsets.Add(new Vector2(x + c * _tileWidth, y + r * _tileHeight));
                    }
                    c++;
                }
                rs += widthInTiles;
                r++;
            }
        }
Пример #3
0
        /// <summary>
        /// Shoots a ray from the start point to the end point.
        /// If/when it passes through a tile, it stores and returns that point.
        /// </summary>
        /// <param name="StartX">The X component of the ray's start.</param>
        /// <param name="StartY">The Y component of the ray's start.</param>
        /// <param name="EndX">The X component of the ray's end.</param>
        /// <param name="EndY">The Y component of the ray's end.</param>
        /// <param name="Result">A <code>Point</code> object containing the first wall impact.</param>
        /// <param name="Resolution">Defaults to 1, meaning check every tile or so.  Higher means more checks!</param>
        /// <returns>Whether or not there was a collision between the ray and a colliding tile.</returns>
        public bool ray(int StartX, int StartY, int EndX, int EndY, Vector2 Result, int Resolution)
        {
            int step = _tileWidth;

            if (_tileHeight < _tileWidth)
            {
                step = _tileHeight;
            }
            step /= Resolution;
            int dx = EndX - StartX;
            //if (dx == 0) return false;
            int dy = EndY - StartY;
            //if (dy == 0) return false;
            float distance = (float)Math.Sqrt(dx * dx + dy * dy);
            int   steps    = (int)FlxU.ceil(distance / step);
            int   stepX    = dx / steps;
            int   stepY    = dy / steps;
            int   curX     = StartX - stepX;
            int   curY     = StartY - stepY;
            int   tx;
            int   ty;
            int   i = 0;


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

                if ((curX < 0) || (curX > width) || (curY < 0) || (curY > height))
                {
                    i++;
                    continue;
                }

                tx = curX / _tileWidth;
                ty = curY / _tileHeight;
                if (_data[ty * widthInTiles + tx] >= collideMin && _data[ty * widthInTiles + tx] <= collideMax)
                {
                    //Some basic helper stuff
                    tx *= _tileWidth;
                    ty *= _tileHeight;
                    int rx = 0;
                    int ry = 0;
                    int q;
                    int lx = curX - stepX;
                    int ly = curY - stepY;

                    //Figure out if it crosses the X boundary
                    q = tx;
                    if (dx < 0)
                    {
                        q += _tileWidth;
                    }
                    rx = q;
                    ry = ly + stepY * ((q - lx) / stepX);
                    if ((ry > ty) && (ry < ty + _tileHeight))
                    {
                        Console.WriteLine("X Result: {0} {1}", rx, ry);
                        Result.X = rx;
                        Result.Y = ry;
                        return(true);
                    }

                    //Else, figure out if it crosses the Y boundary
                    q = ty;
                    if (dy < 0)
                    {
                        q += _tileHeight;
                    }
                    rx = lx + stepX * ((q - ly) / stepY);
                    ry = q;
                    if ((rx > tx) && (rx < tx + _tileWidth))
                    {
                        Console.WriteLine("Y Result: {0} {1}", rx, ry);
                        Result.X = rx;
                        Result.Y = ry;
                        return(true);
                    }
                    return(false);
                }
                i++;
            }
            return(false);
        }
Пример #4
0
        /// <summary>
        /// Load the tilemap with string data and a tile graphic.
        /// </summary>
        /// <param name="MapData">A string of comma and line-return delineated indices indicating what order the tiles should go in. <para>If you want to use 0,1,0,1... use FlxTilemap.OFF, FlxTilemap.AUTO or FlxTilemap.ALT</para><para>If you are using tile ids such as 0,23,12,4,1... use FlxTilemap.STRING</para></param>
        /// <param name="TileGraphic">All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData.</param>
        /// <param name="TileWidth">The width of your tiles (e.g. 8) - defaults to height of the tile graphic if unspecified.</param>
        /// <param name="TileHeight">The height of your tiles (e.g. 8) - defaults to width if unspecified.</param>
        /// <returns>A pointer this instance of FlxTilemap, for chaining as usual :)</returns>
        public FlxTilemap loadMap(string MapData, Texture2D TileGraphic, int TileWidth, int TileHeight)
        {
            refresh = true;

            _tileBitmap = TileGraphic;

            //Figure out the map dimensions based on the data string
            string[] cols;
            string[] rows = MapData.Split('\n');

            //int xxx = 0;
            //foreach (var item in rows)
            //{
            //    Console.WriteLine(xxx + " " + item);
            //    xxx++;
            //}

            heightInTiles = rows.Length;
            int r = 0;
            int c;

            cols  = rows[r].Split(',');
            _data = new int[rows.Length * cols.Length];

            //Console.WriteLine(rows.Length + " " + cols.Length);

            //foreach (var item in _data)
            //    Console.Write(item.ToString() + ",");
            //Console.WriteLine("\n");


            while (r < heightInTiles)
            {
                cols = rows[r++].Split(',');
                if (cols.Length <= 1)
                {
                    heightInTiles = heightInTiles - 1;
                    continue;
                }
                if (widthInTiles == 0)
                {
                    widthInTiles = cols.Length;
                }
                c = 0;

                //Console.WriteLine(widthInTiles + " " + heightInTiles);

                while (c < widthInTiles)
                {
                    //int ff = ((r - 1) * widthInTiles) + c;
                    //Console.WriteLine(r + " " + c + " " + ff);
                    _data[((r - 1) * widthInTiles) + c] = int.Parse(cols[c++]); //.push(uint(cols[c++]));
                }
            }

            //now that height and width have been determined, find how many extra
            //"filler tiles" are at the end of your map.

            int standardLength = TileHeight * TileWidth;
            int graphicWidth   = _tileBitmap.Width;

            _extraMiddleTiles = (graphicWidth - standardLength) / TileWidth;

            //Pre-process the map data if it's auto-tiled
            int i;

            totalTiles = widthInTiles * heightInTiles;
            if (auto == AUTO || auto == ALT)
            {
                collideMin = collideIndex = startingIndex = drawIndex = 1;
                i          = 0;
                while (i < totalTiles)
                {
                    autoTile(i++);
                }
            }
            if (auto == RANDOM)
            {
                collideMin = collideIndex = startingIndex = drawIndex = 1;
                i          = 0;
                while (i < totalTiles)
                {
                    randomTile(i++);
                }
            }

            if (auto == STRING)
            {
                collideMin = collideIndex = startingIndex = drawIndex = 1;
                i          = 0;
                while (i < totalTiles)
                {
                    stringTile(i++);
                }
            }
            if (auto == REMAPAUTO || auto == REMAPALT)
            {
                collideMin = collideIndex = startingIndex = drawIndex = 1;
                i          = 0;
                while (i < totalTiles)
                {
                    autoTileWithRemap(i++);
                }
            }


            //Figure out the size of the tiles
            _tileWidth = TileWidth;
            if (_tileWidth == 0)
            {
                _tileWidth = TileGraphic.Height;
            }
            _tileHeight = TileHeight;
            if (_tileHeight == 0)
            {
                _tileHeight = _tileWidth;
            }
            _block.width  = _tileWidth;
            _block.height = _tileHeight;

            //Then go through and create the actual map
            width  = widthInTiles * _tileWidth;
            height = heightInTiles * _tileHeight;
            _rects = new List <Rectangle>();
            i      = 0;
            while (i < totalTiles)
            {
                _rects.Add(Rectangle.Empty);
                updateTile(i++);
            }

            //Pre-set some helper variables for later
            _screenRows = (int)FlxU.ceil((float)FlxG.height / (float)_tileHeight) + 1;
            if (_screenRows > heightInTiles)
            {
                _screenRows = heightInTiles;
            }
            _screenCols = (int)FlxU.ceil((float)FlxG.width / (float)_tileWidth) + 1;
            if (_screenCols > widthInTiles)
            {
                _screenCols = widthInTiles;
            }

            generateBoundingTiles();
            refreshHulls();

            _flashRect.X      = 0;
            _flashRect.Y      = 0;
            _flashRect.Width  = (int)(FlxU.ceil((float)FlxG.width / (float)_tileWidth) + 1) * _tileWidth;;
            _flashRect.Height = (int)(FlxU.ceil((float)FlxG.height / (float)_tileHeight) + 1) * _tileHeight;

            //foreach (var item in _data)
            //    Console.Write(item.ToString() + ",");
            //Console.WriteLine("\n");

            return(this);
        }
Пример #5
0
        public FlxTilemap loadMap(string MapData, Texture2D TileGraphic, int TileWidth, int TileHeight)
        {
            refresh = true;

            _tileBitmap = TileGraphic;

            //Figure out the map dimensions based on the data string
            string[] cols;
            string[] rows = MapData.Split('\n');
            heightInTiles = rows.Length;
            int r = 0;
            int c;

            cols  = rows[r].Split(',');
            _data = new int[rows.Length * cols.Length];
            while (r < heightInTiles)
            {
                cols = rows[r++].Split(',');
                if (cols.Length <= 1)
                {
                    heightInTiles = heightInTiles - 1;
                    continue;
                }
                if (widthInTiles == 0)
                {
                    widthInTiles = cols.Length;
                }
                c = 0;
                while (c < widthInTiles)
                {
                    _data[((r - 1) * widthInTiles) + c] = int.Parse(cols[c++]);                     //.push(uint(cols[c++]));
                }
            }

            //Pre-process the map data if it's auto-tiled
            int i;

            totalTiles = widthInTiles * heightInTiles;
            if (auto > OFF)
            {
                collideIndex = startingIndex = drawIndex = 1;
                i            = 0;
                while (i < totalTiles)
                {
                    autoTile(i++);
                }
            }

            //Figure out the size of the tiles
            _tileWidth = TileWidth;
            if (_tileWidth == 0)
            {
                _tileWidth = TileGraphic.Height;
            }
            _tileHeight = TileHeight;
            if (_tileHeight == 0)
            {
                _tileHeight = _tileWidth;
            }
            _block.width  = _tileWidth;
            _block.height = _tileHeight;

            //Then go through and create the actual map
            width  = widthInTiles * _tileWidth;
            height = heightInTiles * _tileHeight;
            _rects = new List <Rectangle>();
            i      = 0;
            while (i < totalTiles)
            {
                _rects.Add(Rectangle.Empty);
                updateTile(i++);
            }

            //Pre-set some helper variables for later
            _screenRows = (int)FlxU.ceil((float)FlxG.height / (float)_tileHeight) + 1;
            if (_screenRows > heightInTiles)
            {
                _screenRows = heightInTiles;
            }
            _screenCols = (int)FlxU.ceil((float)FlxG.width / (float)_tileWidth) + 1;
            if (_screenCols > widthInTiles)
            {
                _screenCols = widthInTiles;
            }

            generateBoundingTiles();
            refreshHulls();

            _flashRect.X      = 0;
            _flashRect.Y      = 0;
            _flashRect.Width  = (int)(FlxU.ceil((float)FlxG.width / (float)_tileWidth) + 1) * _tileWidth;;
            _flashRect.Height = (int)(FlxU.ceil((float)FlxG.height / (float)_tileHeight) + 1) * _tileHeight;

            return(this);
        }