public FlxQuadTree(float X, float Y, float Width, float Height, FlxQuadTree Parent = null) : base(X, Y, Width, Height) { _headA = _tailA = new FlxList(); _headB = _tailB = new FlxList(); //Copy the parent's children (if there are any) if(Parent != null) { FlxList iterator; FlxList ot; if(Parent._headA.Object != null) { iterator = Parent._headA; while(iterator != null) { if(_tailA.Object != null) { ot = _tailA; _tailA = new FlxList(); ot.next = _tailA; } _tailA.Object = iterator.Object; iterator = iterator.next; } } if(Parent._headB.Object != null) { iterator = Parent._headB; while(iterator != null) { if(_tailB.Object != null) { ot = _tailB; _tailB = new FlxList(); ot.next = _tailB; } _tailB.Object = iterator.Object; iterator = iterator.next; } } } else _min = (uint)(base.Width + base.Height) / (2 * divisions); _canSubdivide = (base.Width > _min) || (base.Height > _min); //Set up comparison/sort helpers _northWestTree = null; _northEastTree = null; _southEastTree = null; _southWestTree = null; _leftEdge = base.X; _rightEdge = base.X + base.Width; _halfWidth = base.Width / 2; _midpointX = _leftEdge + _halfWidth; _topEdge = base.Y; _bottomEdge = base.Y + base.Height; _halfHeight = base.Height / 2; _midpointY = _topEdge + _halfHeight; }
/// <summary> /// Returns true if the two FlxObjects overlap. Optional Callback function of return type bool with two FlxObject parameters will be called if true. /// </summary> /// <param name="ObjectOrGroup1"></param> /// <param name="ObjectOrGroup2"></param> /// <param name="NotifyCallback"></param> /// <param name="ProcessCallback"></param> /// <returns></returns> static public Boolean overlap(FlxObject ObjectOrGroup1 = null, FlxObject ObjectOrGroup2 = null, Func <FlxObject, FlxObject, Boolean> NotifyCallback = null, Func <FlxObject, FlxObject, Boolean> ProcessCallback = null) { if (ObjectOrGroup1 == null) { ObjectOrGroup1 = FlxG.state; } if (ObjectOrGroup2 == ObjectOrGroup1) { ObjectOrGroup2 = null; } FlxQuadTree.divisions = FlxG.worldDivisions; FlxQuadTree quadTree = new FlxQuadTree(FlxG.worldBounds.x, FlxG.worldBounds.y, FlxG.worldBounds.width, FlxG.worldBounds.height); quadTree.load(ObjectOrGroup1, ObjectOrGroup2, NotifyCallback, ProcessCallback); Boolean result = quadTree.execute(); quadTree.destroy(); return(result); }
public void destroy() { _headA.destroy(); _headA = null; _tailA.destroy(); _tailA = null; _headB.destroy(); _headB = null; _tailB.destroy(); _tailB = null; if (_northWestTree != null) { _northWestTree.destroy(); } _northWestTree = null; if (_northEastTree != null) { _northEastTree.destroy(); } _northEastTree = null; if (_southEastTree != null) { _southEastTree.destroy(); } _southEastTree = null; if (_southWestTree != null) { _southWestTree.destroy(); } _southWestTree = null; _object = null; _processingCallback = null; _notifyCallback = null; }
public FlxQuadTree(float X, float Y, float Width, float Height, FlxQuadTree Parent = null) : base(X, Y, Width, Height) { _headA = _tailA = new FlxList(); _headB = _tailB = new FlxList(); //Copy the parent's children (if there are any) if (Parent != null) { FlxList iterator; FlxList ot; if (Parent._headA.Object != null) { iterator = Parent._headA; while (iterator != null) { if (_tailA.Object != null) { ot = _tailA; _tailA = new FlxList(); ot.next = _tailA; } _tailA.Object = iterator.Object; iterator = iterator.next; } } if (Parent._headB.Object != null) { iterator = Parent._headB; while (iterator != null) { if (_tailB.Object != null) { ot = _tailB; _tailB = new FlxList(); ot.next = _tailB; } _tailB.Object = iterator.Object; iterator = iterator.next; } } } else { _min = (uint)(base.Width + base.Height) / (2 * divisions); } _canSubdivide = (base.Width > _min) || (base.Height > _min); //Set up comparison/sort helpers _northWestTree = null; _northEastTree = null; _southEastTree = null; _southWestTree = null; _leftEdge = base.X; _rightEdge = base.X + base.Width; _halfWidth = base.Width / 2; _midpointX = _leftEdge + _halfWidth; _topEdge = base.Y; _bottomEdge = base.Y + base.Height; _halfHeight = base.Height / 2; _midpointY = _topEdge + _halfHeight; }
protected void addObject() { //If this quad (not its children) lies entirely inside this object, add it here if (!_canSubdivide || ((_leftEdge >= _objectLeftEdge) && (_rightEdge <= _objectRightEdge) && (_topEdge >= _objectTopEdge) && (_bottomEdge <= _objectBottomEdge))) { addToList(); return; } //See if the selected object fits completely inside any of the quadrants if ((_objectLeftEdge > _leftEdge) && (_objectRightEdge < _midpointX)) { if ((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY)) { if (_northWestTree == null) { _northWestTree = new FlxQuadTree(_leftEdge, _topEdge, _halfWidth, _halfHeight, this); } _northWestTree.addObject(); return; } if ((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge)) { if (_southWestTree == null) { _southWestTree = new FlxQuadTree(_leftEdge, _midpointY, _halfWidth, _halfHeight, this); } _southWestTree.addObject(); return; } } if ((_objectLeftEdge > _midpointX) && (_objectRightEdge < _rightEdge)) { if ((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY)) { if (_northEastTree == null) { _northEastTree = new FlxQuadTree(_midpointX, _topEdge, _halfWidth, _halfHeight, this); } _northEastTree.addObject(); return; } if ((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge)) { if (_southEastTree == null) { _southEastTree = new FlxQuadTree(_midpointX, _midpointY, _halfWidth, _halfHeight, this); } _southEastTree.addObject(); return; } } //If it wasn't completely contained we have to check out the partial overlaps if ((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY)) { if (_northWestTree == null) { _northWestTree = new FlxQuadTree(_leftEdge, _topEdge, _halfWidth, _halfHeight, this); } _northWestTree.addObject(); } if ((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY)) { if (_northEastTree == null) { _northEastTree = new FlxQuadTree(_midpointX, _topEdge, _halfWidth, _halfHeight, this); } _northEastTree.addObject(); } if ((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge)) { if (_southEastTree == null) { _southEastTree = new FlxQuadTree(_midpointX, _midpointY, _halfWidth, _halfHeight, this); } _southEastTree.addObject(); } if ((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge)) { if (_southWestTree == null) { _southWestTree = new FlxQuadTree(_leftEdge, _midpointY, _halfWidth, _halfHeight, this); } _southWestTree.addObject(); } }
/// <summary> /// Call this function to see if one <code>FlxObject</code> overlaps another. /// Can be called with one object and one group, or two groups, or two objects, /// whatever floats your boat! For maximum performance try bundling a lot of objects /// together using a <code>FlxGroup</code> (or even bundling groups together!). /// /// <p>NOTE: does NOT take objects' scrollfactor into account, all overlaps are checked in world space.</p> /// </summary> /// <param name="ObjectOrGroup1">The first object or group you want to check.</param> /// <param name="ObjectOrGroup2">The second object or group you want to check. If it is the same as the first, flixel knows to just do a comparison within that group.</param> /// <param name="NotifyCallback">A function with two <code>FlxObject</code> parameters - e.g. <code>myOverlapFunction(Object1:FlxObject,Object2:FlxObject)</code> - that is called if those two objects overlap.</param> /// <param name="ProcessCallback">A function with two <code>FlxObject</code> parameters - e.g. <code>myOverlapFunction(Object1:FlxObject,Object2:FlxObject)</code> - that is called if those two objects overlap. If a ProcessCallback is provided, then NotifyCallback will only be called if ProcessCallback returns true for those objects!</param> /// <returns></returns> public static Boolean overlap(FlxObject ObjectOrGroup1 = null, FlxObject ObjectOrGroup2 = null, Func<FlxObject, FlxObject, Boolean> NotifyCallback = null, Func<FlxObject, FlxObject, Boolean> ProcessCallback = null) { if (ObjectOrGroup1 == null) { ObjectOrGroup1 = FlxG.State; } if (ObjectOrGroup2 == ObjectOrGroup1) { ObjectOrGroup2 = null; } FlxQuadTree.divisions = FlxG.worldDivisions; FlxQuadTree quadTree = new FlxQuadTree(FlxG.worldBounds.X, FlxG.worldBounds.Y, FlxG.worldBounds.Width, FlxG.worldBounds.Height); quadTree.load(ObjectOrGroup1, ObjectOrGroup2, NotifyCallback, ProcessCallback); Boolean result = quadTree.execute(); quadTree.destroy(); return result; }
protected void addObject() { //If this quad (not its children) lies entirely inside this object, add it here if(!_canSubdivide || ((_leftEdge >= _objectLeftEdge) && (_rightEdge <= _objectRightEdge) && (_topEdge >= _objectTopEdge) && (_bottomEdge <= _objectBottomEdge))) { addToList(); return; } //See if the selected object fits completely inside any of the quadrants if((_objectLeftEdge > _leftEdge) && (_objectRightEdge < _midpointX)) { if((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY)) { if(_northWestTree == null) _northWestTree = new FlxQuadTree(_leftEdge,_topEdge,_halfWidth,_halfHeight,this); _northWestTree.addObject(); return; } if((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge)) { if(_southWestTree == null) _southWestTree = new FlxQuadTree(_leftEdge,_midpointY,_halfWidth,_halfHeight,this); _southWestTree.addObject(); return; } } if((_objectLeftEdge > _midpointX) && (_objectRightEdge < _rightEdge)) { if((_objectTopEdge > _topEdge) && (_objectBottomEdge < _midpointY)) { if(_northEastTree == null) _northEastTree = new FlxQuadTree(_midpointX,_topEdge,_halfWidth,_halfHeight,this); _northEastTree.addObject(); return; } if((_objectTopEdge > _midpointY) && (_objectBottomEdge < _bottomEdge)) { if(_southEastTree == null) _southEastTree = new FlxQuadTree(_midpointX,_midpointY,_halfWidth,_halfHeight,this); _southEastTree.addObject(); return; } } //If it wasn't completely contained we have to check out the partial overlaps if((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY)) { if(_northWestTree == null) _northWestTree = new FlxQuadTree(_leftEdge,_topEdge,_halfWidth,_halfHeight,this); _northWestTree.addObject(); } if((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _topEdge) && (_objectTopEdge < _midpointY)) { if(_northEastTree == null) _northEastTree = new FlxQuadTree(_midpointX,_topEdge,_halfWidth,_halfHeight,this); _northEastTree.addObject(); } if((_objectRightEdge > _midpointX) && (_objectLeftEdge < _rightEdge) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge)) { if(_southEastTree == null) _southEastTree = new FlxQuadTree(_midpointX,_midpointY,_halfWidth,_halfHeight,this); _southEastTree.addObject(); } if((_objectRightEdge > _leftEdge) && (_objectLeftEdge < _midpointX) && (_objectBottomEdge > _midpointY) && (_objectTopEdge < _bottomEdge)) { if(_southWestTree == null) _southWestTree = new FlxQuadTree(_leftEdge,_midpointY,_halfWidth,_halfHeight,this); _southWestTree.addObject(); } }
public void destroy() { _headA.destroy(); _headA = null; _tailA.destroy(); _tailA = null; _headB.destroy(); _headB = null; _tailB.destroy(); _tailB = null; if(_northWestTree != null) _northWestTree.destroy(); _northWestTree = null; if(_northEastTree != null) _northEastTree.destroy(); _northEastTree = null; if(_southEastTree != null) _southEastTree.destroy(); _southEastTree = null; if(_southWestTree != null) _southWestTree.destroy(); _southWestTree = null; _object = null; _processingCallback = null; _notifyCallback = null; }