/** * Clean up memory. */ public void destroy() { Object = null; if(next != null) next.destroy(); next = null; }
public FlxTilemap() : base() { auto = OFF; widthInTiles = 0; heightInTiles = 0; totalTiles = 0; tileGraphic = null; _rects = null; _tiles = null; _tileObjectsForDrawing = new List<FlxTile>(); _tileObjects = null; _tileWidth = 0; _tileHeight = 0; Immovable = true; _block = new FlxObject(); _block.Width = _block.Height = 0; _block.Immovable = true; _startingIndex = 0; collideIndex = 1; AllowCollisions = Any; ID = 3; }
/** * Creates a new link, and sets <code>object</code> and <code>next</code> to <code>null</code>. */ public FlxList() { Object = null; next = null; }
/// <summary> /// Change the emitter's position to the origin of a <code>FlxObject</code>. /// /// @param Object The <code>FlxObject</code> that needs to spew particles. /// </summary> public void At(FlxObject Object) { X = Object.X + Object.origin.X; Y = Object.Y + Object.origin.Y; }
void Hit(FlxObject ball, FlxObject brick) { brick.Exists = false; }
/// <summary> /// The Y-axis component of the object separation process. /// </summary> /// <param name="objectOne">Any <code>FlxObject</code>.</param> /// <param name="objectTwo">Any other <code>FlxObject</code>.</param> /// <returns></returns> public static bool separateY(FlxObject objectOne, FlxObject objectTwo) { //can't separate two immovable objects bool obj1immovable = objectOne.Immovable; bool obj2immovable = objectTwo.Immovable; if(obj1immovable && obj2immovable) return false; ////If one of the objects is a tilemap, just pass it off. if (objectOne is FlxTilemap) return (objectOne as FlxTilemap).overlapsWithCallback(objectTwo, separateY); if (objectTwo is FlxTilemap) return (objectTwo as FlxTilemap).overlapsWithCallback(objectOne, separateY, true); //First, get the two object deltas float overlap = 0; float obj1delta = objectOne.Y - objectOne.Last.Y; float obj2delta = objectTwo.Y - objectTwo.Last.Y; if(obj1delta != obj2delta) { //Check if the Y hulls actually overlap float obj1deltaAbs = (obj1delta > 0) ? obj1delta : -obj1delta; float obj2deltaAbs = (obj2delta > 0) ? obj2delta : -obj2delta; FlxRect obj1rect = new FlxRect(objectOne.X,objectOne.Y-((obj1delta > 0)?obj1delta:0),objectOne.Width,objectOne.Height+obj1deltaAbs); FlxRect obj2rect = new FlxRect(objectTwo.X,objectTwo.Y-((obj2delta > 0)?obj2delta:0),objectTwo.Width,objectTwo.Height+obj2deltaAbs); if((obj1rect.X + obj1rect.Width > obj2rect.X) && (obj1rect.X < obj2rect.X + obj2rect.Width) && (obj1rect.Y + obj1rect.Height > obj2rect.Y) && (obj1rect.Y < obj2rect.Y + obj2rect.Height)) { float maxOverlap = obj1deltaAbs + obj2deltaAbs + OverlapBias; //If they did overlap (and can), figure out by how much and flip the corresponding flags if(obj1delta > obj2delta) { overlap = objectOne.Y + objectOne.Height - objectTwo.Y; if((overlap > maxOverlap) || !Convert.ToBoolean(objectOne.AllowCollisions & Down) || !Convert.ToBoolean(objectTwo.AllowCollisions & Up)) overlap = 0; else { objectOne.Touching |= Down; objectTwo.Touching |= Up; } } else if(obj1delta < obj2delta) { overlap = objectOne.Y - objectTwo.Height - objectTwo.Y; if((-overlap > maxOverlap) || !Convert.ToBoolean(objectOne.AllowCollisions & Up) || !Convert.ToBoolean(objectTwo.AllowCollisions & Down)) overlap = 0; else { objectOne.Touching |= Up; objectTwo.Touching |= Down; } } } } //Then adjust their positions and velocities accordingly (if there was any overlap) if(overlap != 0) { float obj1v = objectOne.Velocity.Y; float obj2v = objectTwo.Velocity.Y; if(!obj1immovable && !obj2immovable) { overlap *= 0.5f; objectOne.Y = objectOne.Y - overlap; objectTwo.Y += overlap; float obj1velocity = (float)Math.Sqrt((obj2v * obj2v * objectTwo.Mass) / objectOne.Mass) * ((obj2v > 0) ? 1f : -1f); float obj2velocity = (float)Math.Sqrt((obj1v * obj1v * objectOne.Mass) / objectTwo.Mass) * ((obj1v > 0) ? 1f : -1f); float average = (obj1velocity + obj2velocity) * 0.5f; obj1velocity -= average; obj2velocity -= average; objectOne.Velocity.Y = average + obj1velocity * objectOne.Elasticity; objectTwo.Velocity.Y = average + obj2velocity * objectTwo.Elasticity; } else if(!obj1immovable) { objectOne.Y = objectOne.Y - overlap; objectOne.Velocity.Y = obj2v - obj1v*objectOne.Elasticity; //This is special case code that handles cases like horizontal moving platforms you can ride if(objectTwo.Active && objectTwo.Moves && (obj1delta > obj2delta)) objectOne.X += objectTwo.X - objectTwo.Last.X; } else if(!obj2immovable) { objectTwo.Y += overlap; objectTwo.Velocity.Y = obj1v - obj2v*objectTwo.Elasticity; //This is special case code that handles cases like horizontal moving platforms you can ride if(objectOne.Active && objectOne.Moves && (obj1delta < obj2delta)) objectTwo.X += objectOne.X - objectOne.Last.X; } return true; } else return false; }
/// <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; }
public Boolean execute() { Boolean overlapProcessed = false; FlxList iterator; if(_headA.Object != null) { iterator = _headA; while(iterator != null) { _object = iterator.Object; if(_useBothLists) _iterator = _headB; else _iterator = iterator.next; if( _object.Exists && (_object.AllowCollisions > 0) && (_iterator != null) && (_iterator.Object != null) && _iterator.Object.Exists && overlapNode()) { overlapProcessed = true; } iterator = iterator.next; } } //Advance through the tree by calling overlap on each child if((_northWestTree != null) && _northWestTree.execute()) overlapProcessed = true; if((_northEastTree != null) && _northEastTree.execute()) overlapProcessed = true; if((_southEastTree != null) && _southEastTree.execute()) overlapProcessed = true; if((_southWestTree != null) && _southWestTree.execute()) overlapProcessed = true; return overlapProcessed; }
//@desc Tells the camera subsystem what FlxCore object to follow //@param Target The object to follow //@param Lerp How much lag the camera should have (can help smooth out the camera movement) public static void follow(FlxObject Target, float Lerp) { followTarget = Target; followLerp = Lerp; if (Target == null) return; scroll.X = _scrollTarget.X = (width >> 1) - followTarget.X - ((int)followTarget.Width >> 1); scroll.Y = _scrollTarget.Y = (height >> 1) - followTarget.Y - ((int)followTarget.Height >> 1); }
public void add(FlxBasic ObjectOrGroup, uint List) { _list = List; if(ObjectOrGroup is FlxGroup) { uint i = 0; FlxBasic basic; List<FlxBasic> members = new List<FlxBasic>(); members = (ObjectOrGroup as FlxGroup).Members; uint l = (uint)members.Count; while(i < l) { basic = members[(int)i++] as FlxBasic; if((basic != null) && basic.Exists) { if(basic is FlxGroup) add(basic,List); else if(basic is FlxObject) { _object = basic as FlxObject; if(_object.Exists && Convert.ToBoolean(_object.AllowCollisions)) { _objectLeftEdge = _object.X; _objectTopEdge = _object.Y; _objectRightEdge = _object.X + _object.Width; _objectBottomEdge = _object.Y + _object.Height; addObject(); } } } } } else { _object = ObjectOrGroup as FlxObject; if(_object.Exists && Convert.ToBoolean(_object.AllowCollisions) ) { _objectLeftEdge = _object.X; _objectTopEdge = _object.Y; _objectRightEdge = _object.X + _object.Width; _objectBottomEdge = _object.Y + _object.Height; 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; }
/// <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. /// /// @param Object The <code>FlxObject</code> you're about to run into. /// </summary> public override 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] >= collideIndex) { colOffsets.Add(new Vector2(X + c * _tileWidth, Y + r * _tileHeight)); } c++; } rs += widthInTiles; r++; } }
/// <summary> /// Checks for overlaps between the provided object and any tiles above the collision index. /// /// @param Core The <code>FlxObject</code> you want to check against. /// </summary> public override 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 >= collideIndex) 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; }
/// <summary> /// The tilemap constructor just initializes some basic variables. /// </summary> public FlxTilemap() { if (ImgAuto == null || ImgAutoAlt == null) { ImgAuto = FlxG.Game.Content.Load<Texture2D>("flixel/autotiles"); ImgAutoAlt = FlxG.Game.Content.Load<Texture2D>("flixel/autotiles_alt"); } auto = OFF; collideIndex = 1; startingIndex = 0; drawIndex = 1; widthInTiles = 0; heightInTiles = 0; totalTiles = 0; _flashRect2 = new Rectangle(); _flashRect = _flashRect2; _data = null; _tileWidth = 0; _tileHeight = 0; _rects = null; _block = new FlxObject(); _block.Width = _block.Height = 0; _block.Fixed = true; //_callbacks = new Array(); Fixed = true; Moves = false; }
/// <summary> /// The main collision resolution function in flixel. /// </summary> /// <param name="objectOne">Any <code>FlxObject</code>.</param> /// <param name="objectTwo">Any other <code>FlxObject</code>.</param> /// <returns>Whether the objects in fact touched and were separated.</returns> public static bool separate(FlxObject objectOne, FlxObject objectTwo) { bool separatedX = separateX(objectOne, objectTwo); bool separatedY = separateY(objectOne, objectTwo); return separatedX || separatedY; }
/// <summary> /// Stops and resets the camera. /// </summary> internal static void unfollow() { followTarget = null; followLead = Vector2.Zero; followLerp = 1; followMin = Point.Zero; followMax = Point.Zero; scroll = new Vector2(); _scrollTarget = new Vector2(); }
/// <summary> /// The X-axis component of the object separation process. /// </summary> /// <param name="objectOne">Any <code>FlxObject</code>.</param> /// <param name="objectTwo">Any other <code>FlxObject</code>.</param> /// <returns></returns> public static bool separateX(FlxObject objectOne, FlxObject objectTwo) { // can't separate two immovable objects bool obj1immovable = objectOne.Immovable; bool obj2immovable = objectTwo.Immovable; if(obj1immovable && obj2immovable) return false; // If one of the objects is a tilemap, just pass it off. if (objectOne is FlxTilemap) return (objectOne as FlxTilemap).overlapsWithCallback(objectTwo, separateX); if (objectTwo is FlxTilemap) return (objectTwo as FlxTilemap).overlapsWithCallback(objectOne, separateX, true); // First, get the two object deltas float overlap = 0; float obj1delta = objectOne.X - objectOne.Last.X; float obj2delta = objectTwo.X - objectTwo.Last.X; if(obj1delta != obj2delta) { //Check if the X hulls actually overlap float obj1deltaAbs = (obj1delta > 0) ? obj1delta : -obj1delta; float obj2deltaAbs = (obj2delta > 0) ? obj2delta : -obj2delta; FlxRect obj1rect = new FlxRect(objectOne.X-((obj1delta > 0)?obj1delta:0),objectOne.Last.Y,objectOne.Width+((obj1delta > 0)?obj1delta:-obj1delta),objectOne.Height); FlxRect obj2rect = new FlxRect(objectTwo.X-((obj2delta > 0)?obj2delta:0),objectTwo.Last.Y,objectTwo.Width+((obj2delta > 0)?obj2delta:-obj2delta),objectTwo.Height); if((obj1rect.X + obj1rect.Width > obj2rect.X) && (obj1rect.X < obj2rect.X + obj2rect.Width) && (obj1rect.Y + obj1rect.Height > obj2rect.Y) && (obj1rect.Y < obj2rect.Y + obj2rect.Height)) { float maxOverlap = obj1deltaAbs + obj2deltaAbs + OverlapBias; //If they did overlap (and can), figure out by how much and flip the corresponding flags if(obj1delta > obj2delta) { overlap = objectOne.X + objectOne.Width - objectTwo.X; if((overlap > maxOverlap) || !Convert.ToBoolean(objectOne.AllowCollisions & Right) || !Convert.ToBoolean(objectTwo.AllowCollisions & Left)) overlap = 0; else { objectOne.Touching |= Right; objectTwo.Touching |= Left; } } else if(obj1delta < obj2delta) { overlap = objectOne.X - objectTwo.Width - objectTwo.X; if((-overlap > maxOverlap) || !Convert.ToBoolean(objectOne.AllowCollisions & Left) || !Convert.ToBoolean(objectTwo.AllowCollisions & Right)) overlap = 0; else { objectOne.Touching |= Left; objectTwo.Touching |= Right; } } } } //Then adjust their positions and velocities accordingly (if there was any overlap) if(overlap != 0) { float obj1v = objectOne.Velocity.X; float obj2v = objectTwo.Velocity.X; if(!obj1immovable && !obj2immovable) { overlap *= 0.5f; objectOne.X = objectOne.X - overlap; objectTwo.X += overlap; float obj1velocity = (float)Math.Sqrt((obj2v * obj2v * objectTwo.Mass) / objectOne.Mass) * ((obj2v > 0) ? 1f : -1f); float obj2velocity = (float)Math.Sqrt((obj1v * obj1v * objectOne.Mass) / objectTwo.Mass) * ((obj1v > 0) ? 1f : -1f); float average = (obj1velocity + obj2velocity) * 0.5f; obj1velocity -= average; obj2velocity -= average; objectOne.Velocity.X = average + obj1velocity * objectOne.Elasticity; objectTwo.Velocity.X = average + obj2velocity * objectTwo.Elasticity; } else if(!obj1immovable) { objectOne.X = objectOne.X - overlap; objectOne.Velocity.X = obj2v - obj1v*objectOne.Elasticity; } else if(!obj2immovable) { objectTwo.X += overlap; objectTwo.Velocity.X = obj1v - obj2v*objectTwo.Elasticity; } return true; } else return false; }
public FlxSpriteCollisionEvent(FlxObject Attacker, FlxObject Target) { _s1 = Attacker; _s2 = Target; }
/// <summary> /// 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! For maximum performance try bundling a lot of objects /// together using a <code>FlxGroup</code> (or even bundling groups together!). /// /// <p>This function just calls FlxG.overlap and presets the ProcessCallback parameter to FlxObject.separate. /// To create your own collision logic, write your own ProcessCallback and use FlxG.overlap to set it up.</p> /// /// <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> /// <returns>Whether any objects were successfully collided/separated.</returns> public static Boolean collide(FlxObject objectOrGroup1 = null, FlxObject objectOrGroup2 = null, Func<FlxObject, FlxObject, Boolean> notifyCallback = null) { return overlap(objectOrGroup1, objectOrGroup2, notifyCallback, FlxObject.separate); }
// 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; }
/// <summary> /// Change the emitter's midpoint to match the midpoint of a <code>FlxObject</code>. /// </summary> /// <param name="flxObject">The <code>FlxObject</code> that you want to sync up with.</param> public void at(FlxObject flxObject) { flxObject.getMidpoint(_point); X = _point.X - (Convert.ToInt32(Width)>>1); Y = _point.Y - (Convert.ToInt32(Height)>>1); }
public override void overlapped(FlxObject obj) { base.overlapped(obj); }