// 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); }
/** * 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); }