/** * Clean up memory. */ public void destroy() { if (_headA != null) { _headA.destroy(); } _headA = null; // if(_tailA != null) // _tailA.destroy(); _tailA = null; if (_headB != null) { _headB.destroy(); } _headB = null; // if(_tailB != 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; //_pool.free(this); }
/** * Internal function for recursively navigating and creating the tree while * adding objects to the appropriate nodes. */ 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(); } }
/** * Internal, a pool of <code>FlxQuadTree</code>s to prevent constant * <code>new</code> calls. * * static private Pool<FlxQuadTree> _pool = new Pool<FlxQuadTree>() * { * @Override * protected FlxQuadTree newObject() * { * return new FlxQuadTree(); * } * }; */ /** * Get a new Quad Tree node from the pool. * * @param X The X-coordinate of the point in space. * @param Y The Y-coordinate of the point in space. * @param Width Desired width of this node. * @param Height Desired height of this node. * @param Parent The parent branch or node. Pass null to create a root. * * @return A new <code>FlxQuadTree</code>. * * static public FlxQuadTree getNew(float X, float Y, float Width, float Height, FlxQuadTree Parent) * { * FlxQuadTree quadTree = _pool.obtain(); * quadTree.init(X, Y, Width, Height, Parent); * return quadTree; * } */ /** * Has to be public for GWT reflection. */ public FlxQuadTree(float X, float Y, float Width, float Height, FlxQuadTree Parent = null) { init(X, Y, Width, Height, Parent); }
/** * Instantiate a new Quad Tree node. * * @param X The X-coordinate of the point in space. * @param Y The Y-coordinate of the point in space. * @param Width Desired width of this node. * @param Height Desired height of this node. * @param Parent The parent branch or node. Pass null to create a root. */ protected void init(float X, float Y, float Width, float Height, FlxQuadTree Parent) { make(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 = (int)((Width + Height) / (2 * divisions)); } _canSubdivide = (Width > _min) || (Height > _min); // Set up comparison/sort helpers _northWestTree = null; _northEastTree = null; _southEastTree = null; _southWestTree = null; _leftEdge = X; _rightEdge = X + Width; _halfWidth = Width / 2f; _midpointX = _leftEdge + _halfWidth; _topEdge = Y; _bottomEdge = Y + Height; _halfHeight = Height / 2f; _midpointY = _topEdge + _halfHeight; }
/// <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; }
/** * Instantiate a new Quad Tree node. * * @param X The X-coordinate of the point in space. * @param Y The Y-coordinate of the point in space. * @param Width Desired width of this node. * @param Height Desired height of this node. * @param Parent The parent branch or node. Pass null to create a root. */ protected void init(float X, float Y, float Width, float Height, FlxQuadTree Parent) { make (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 = (int)((Width + Height) / (2 * divisions)); _canSubdivide = (Width > _min) || (Height > _min); // Set up comparison/sort helpers _northWestTree = null; _northEastTree = null; _southEastTree = null; _southWestTree = null; _leftEdge = X; _rightEdge = X + Width; _halfWidth = Width / 2f; _midpointX = _leftEdge + _halfWidth; _topEdge = Y; _bottomEdge = Y + Height; _halfHeight = Height / 2f; _midpointY = _topEdge + _halfHeight; }
/** * Internal function for recursively navigating and creating the tree while * adding objects to the appropriate nodes. */ 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 (); } }
/** * Clean up memory. */ public void destroy() { if (_headA != null) _headA.destroy (); _headA = null; // if(_tailA != null) // _tailA.destroy(); _tailA = null; if (_headB != null) _headB.destroy (); _headB = null; // if(_tailB != 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; //_pool.free(this); }
/** * Internal, a pool of <code>FlxQuadTree</code>s to prevent constant * <code>new</code> calls. static private Pool<FlxQuadTree> _pool = new Pool<FlxQuadTree>() { @Override protected FlxQuadTree newObject() { return new FlxQuadTree(); } }; */ /** * Get a new Quad Tree node from the pool. * * @param X The X-coordinate of the point in space. * @param Y The Y-coordinate of the point in space. * @param Width Desired width of this node. * @param Height Desired height of this node. * @param Parent The parent branch or node. Pass null to create a root. * * @return A new <code>FlxQuadTree</code>. static public FlxQuadTree getNew(float X, float Y, float Width, float Height, FlxQuadTree Parent) { FlxQuadTree quadTree = _pool.obtain(); quadTree.init(X, Y, Width, Height, Parent); return quadTree; } */ /** * Has to be public for GWT reflection. */ public FlxQuadTree(float X, float Y, float Width, float Height, FlxQuadTree Parent = null) { init (X, Y, Width, Height, Parent); }