/** * Call this function to see if one <code>FlxObject</code> collides with another. * Can be called with one object and one group, or two groups, or two objects, * whatever floats your boat! It will put everything into a quad tree and then * check for collisions. For maximum performance try bundling a lot of objects * together using a <code>FlxGroup</code> (even bundling groups together!) * NOTE: does NOT take objects' scrollfactor into account. * * @param Object1 The first object or group you want to check. * @param Object2 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. */ public static bool collide(FlxObject Object1, FlxObject Object2) { if( (Object1 == null) || !Object1.exists || (Object2 == null) || !Object2.exists ) return false; quadTree = new FlxQuadTree(FlxQuadTree.bounds.x,FlxQuadTree.bounds.y,FlxQuadTree.bounds.width,FlxQuadTree.bounds.height,null); quadTree.add(Object1,FlxQuadTree.A_LIST); bool match = Object1 == Object2; if(!match) quadTree.add(Object2,FlxQuadTree.B_LIST); bool cx = quadTree.overlap(!match,solveXCollision); bool cy = quadTree.overlap(!match,solveYCollision); return cx || cy; }
/** * 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! It will put everything into a quad tree and then * check for overlaps. For maximum performance try bundling a lot of objects * together using a <code>FlxGroup</code> (even bundling groups together!) * NOTE: does NOT take objects' scrollfactor into account. * * @param Object1 The first object or group you want to check. * @param Object2 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 Callback A function with two <code>FlxObject</code> parameters - e.g. <code>myOverlapFunction(Object1:FlxObject,Object2:FlxObject);</code> If no function is provided, <code>FlxQuadTree</code> will call <code>kill()</code> on both objects. */ static public bool overlap(FlxObject Object1, FlxObject Object2, SpriteCollisionEvent Callback) { if ((Object1 == null) || !Object1.exists || (Object2 == null) || !Object2.exists) { return(false); } quadTree = new FlxQuadTree(FlxQuadTree.bounds.x, FlxQuadTree.bounds.y, FlxQuadTree.bounds.width, FlxQuadTree.bounds.height, null); quadTree.add(Object1, FlxQuadTree.A_LIST); if (Object1 == Object2) { return(quadTree.overlap(false, Callback)); } quadTree.add(Object2, FlxQuadTree.B_LIST); return(quadTree.overlap(true, Callback)); }
/** * Call this function to see if one <code>FlxObject</code> collides with another. * Can be called with one object and one group, or two groups, or two objects, * whatever floats your boat! It will put everything into a quad tree and then * check for collisions. For maximum performance try bundling a lot of objects * together using a <code>FlxGroup</code> (even bundling groups together!) * NOTE: does NOT take objects' scrollfactor into account. * * @param Object1 The first object or group you want to check. * @param Object2 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. */ static public bool collide(FlxObject Object1, FlxObject Object2) { if ((Object1 == null) || !Object1.exists || (Object2 == null) || !Object2.exists) { return(false); } quadTree = new FlxQuadTree(FlxQuadTree.bounds.x, FlxQuadTree.bounds.y, FlxQuadTree.bounds.width, FlxQuadTree.bounds.height, null); quadTree.add(Object1, FlxQuadTree.A_LIST); bool match = Object1 == Object2; if (!match) { quadTree.add(Object2, FlxQuadTree.B_LIST); } bool cx = quadTree.overlap(!match, solveXCollision); bool cy = quadTree.overlap(!match, solveYCollision); return(cx || cy); }
/** * 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! It will put everything into a quad tree and then * check for overlaps. For maximum performance try bundling a lot of objects * together using a <code>FlxGroup</code> (even bundling groups together!) * NOTE: does NOT take objects' scrollfactor into account. * * @param Object1 The first object or group you want to check. * @param Object2 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 Callback A function with two <code>FlxObject</code> parameters - e.g. <code>myOverlapFunction(Object1:FlxObject,Object2:FlxObject);</code> If no function is provided, <code>FlxQuadTree</code> will call <code>kill()</code> on both objects. */ public static bool overlap(FlxObject Object1, FlxObject Object2, SpriteCollisionEvent Callback) { if( (Object1 == null) || !Object1.exists || (Object2 == null) || !Object2.exists ) return false; quadTree = new FlxQuadTree(FlxQuadTree.bounds.x,FlxQuadTree.bounds.y,FlxQuadTree.bounds.width,FlxQuadTree.bounds.height, null); quadTree.add(Object1,FlxQuadTree.A_LIST); if(Object1 == Object2) return quadTree.overlap(false,Callback); quadTree.add(Object2,FlxQuadTree.B_LIST); return quadTree.overlap(true,Callback); }
/** * 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 || ((_l >= _ol) && (_r <= _or) && (_t >= _ot) && (_b <= _ob))) { addToList(); return; } //See if the selected object fits completely inside any of the quadrants if ((_ol > _l) && (_or < _mx)) { if ((_ot > _t) && (_ob < _my)) { if (_nw == null) { _nw = new FlxQuadTree((int)_l, (int)_t, (int)_hw, (int)_hh, this); } _nw.addObject(); return; } if ((_ot > _my) && (_ob < _b)) { if (_sw == null) { _sw = new FlxQuadTree((int)_l, (int)_my, (int)_hw, (int)_hh, this); } _sw.addObject(); return; } } if ((_ol > _mx) && (_or < _r)) { if ((_ot > _t) && (_ob < _my)) { if (_ne == null) { _ne = new FlxQuadTree((int)_mx, (int)_t, (int)_hw, (int)_hh, this); } _ne.addObject(); return; } if ((_ot > _my) && (_ob < _b)) { if (_se == null) { _se = new FlxQuadTree((int)_mx, (int)_my, (int)_hw, (int)_hh, this); } _se.addObject(); return; } } //If it wasn't completely contained we have to check out the partial overlaps if ((_or > _l) && (_ol < _mx) && (_ob > _t) && (_ot < _my)) { if (_nw == null) { _nw = new FlxQuadTree((int)_l, (int)_t, (int)_hw, (int)_hh, this); } _nw.addObject(); } if ((_or > _mx) && (_ol < _r) && (_ob > _t) && (_ot < _my)) { if (_ne == null) { _ne = new FlxQuadTree((int)_mx, (int)_t, (int)_hw, (int)_hh, this); } _ne.addObject(); } if ((_or > _mx) && (_ol < _r) && (_ob > _my) && (_ot < _b)) { if (_se == null) { _se = new FlxQuadTree((int)_mx, (int)_my, (int)_hw, (int)_hh, this); } _se.addObject(); } if ((_or > _l) && (_ol < _mx) && (_ob > _my) && (_ot < _b)) { if (_sw == null) { _sw = new FlxQuadTree((int)_l, (int)_my, (int)_hw, (int)_hh, this); } _sw.addObject(); } }
/** * 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. */ public FlxQuadTree(float X, float Y, float Width, float Height, FlxQuadTree Parent) { x = X; y = Y; width = Width; height = Height; //x = 0; //y = 0; //width = 0; //height = 0; _headA = _tailA = new FlxList(); _headB = _tailB = new FlxList(); /*DEBUG: draw a randomly colored rectangle indicating this quadrant (may induce seizures) * var brush:FlxSprite = new FlxSprite().createGraphic(Width,Height,0xffffffff*FlxU.random()); * FlxState.screen.draw(brush,X+FlxG.scroll.x,Y+FlxG.scroll.y);//*/ //Copy the parent's children (if there are any) if (Parent != null) { FlxList itr; FlxList ot; if (Parent._headA.@object != null) { itr = Parent._headA; while (itr != null) { if (_tailA.@object != null) { ot = _tailA; _tailA = new FlxList(); ot.next = _tailA; } _tailA.@object = itr.@object; itr = itr.next; } } if (Parent._headB.@object != null) { itr = Parent._headB; while (itr != null) { if (_tailB.@object != null) { ot = _tailB; _tailB = new FlxList(); ot.next = _tailB; } _tailB.@object = itr.@object; itr = itr.next; } } } else { _min = (uint)(width + height) / (2 * divisions); } _canSubdivide = (width > _min) || (height > _min); //Set up comparison/sort helpers _nw = null; _ne = null; _se = null; _sw = null; _l = x; _r = x + width; _hw = width / 2; _mx = _l + _hw; _t = y; _b = y + height; _hh = height / 2; _my = _t + _hh; }
/** * 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 || ((_l >= _ol) && (_r <= _or) && (_t >= _ot) && (_b <= _ob))) { addToList(); return; } //See if the selected object fits completely inside any of the quadrants if((_ol > _l) && (_or < _mx)) { if((_ot > _t) && (_ob < _my)) { if(_nw == null) _nw = new FlxQuadTree((int)_l, (int)_t, (int)_hw, (int)_hh, this); _nw.addObject(); return; } if((_ot > _my) && (_ob < _b)) { if(_sw == null) _sw = new FlxQuadTree((int)_l, (int)_my, (int)_hw, (int)_hh, this); _sw.addObject(); return; } } if((_ol > _mx) && (_or < _r)) { if((_ot > _t) && (_ob < _my)) { if(_ne == null) _ne = new FlxQuadTree((int)_mx, (int)_t, (int)_hw, (int)_hh, this); _ne.addObject(); return; } if((_ot > _my) && (_ob < _b)) { if(_se == null) _se = new FlxQuadTree((int)_mx, (int)_my, (int)_hw, (int) _hh, this); _se.addObject(); return; } } //If it wasn't completely contained we have to check out the partial overlaps if((_or > _l) && (_ol < _mx) && (_ob > _t) && (_ot < _my)) { if(_nw == null) _nw = new FlxQuadTree((int)_l, (int)_t, (int)_hw, (int)_hh, this); _nw.addObject(); } if((_or > _mx) && (_ol < _r) && (_ob > _t) && (_ot < _my)) { if(_ne == null) _ne = new FlxQuadTree((int)_mx, (int)_t, (int)_hw, (int)_hh, this); _ne.addObject(); } if((_or > _mx) && (_ol < _r) && (_ob > _my) && (_ot < _b)) { if(_se == null) _se = new FlxQuadTree((int)_mx, (int)_my, (int)_hw, (int)_hh, this); _se.addObject(); } if((_or > _l) && (_ol < _mx) && (_ob > _my) && (_ot < _b)) { if(_sw == null) _sw = new FlxQuadTree((int)_l, (int)_my, (int)_hw, (int)_hh, this); _sw.addObject(); } }
/** * 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. */ public FlxQuadTree(float X, float Y, float Width, float Height, FlxQuadTree Parent) { x = X; y = Y; width = Width; height = Height; //x = 0; //y = 0; //width = 0; //height = 0; _headA = _tailA = new FlxList(); _headB = _tailB = new FlxList(); /*DEBUG: draw a randomly colored rectangle indicating this quadrant (may induce seizures) var brush:FlxSprite = new FlxSprite().createGraphic(Width,Height,0xffffffff*FlxU.random()); FlxState.screen.draw(brush,X+FlxG.scroll.x,Y+FlxG.scroll.y);//*/ //Copy the parent's children (if there are any) if (Parent != null) { FlxList itr; FlxList ot; if (Parent._headA.@object != null) { itr = Parent._headA; while (itr != null) { if (_tailA.@object != null) { ot = _tailA; _tailA = new FlxList(); ot.next = _tailA; } _tailA.@object = itr.@object; itr = itr.next; } } if (Parent._headB.@object != null) { itr = Parent._headB; while (itr != null) { if (_tailB.@object != null) { ot = _tailB; _tailB = new FlxList(); ot.next = _tailB; } _tailB.@object = itr.@object; itr = itr.next; } } } else _min = (uint)(width + height) / (2 * divisions); _canSubdivide = (width > _min) || (height > _min); //Set up comparison/sort helpers _nw = null; _ne = null; _se = null; _sw = null; _l = x; _r = x + width; _hw = width / 2; _mx = _l + _hw; _t = y; _b = y + height; _hh = height / 2; _my = _t + _hh; }