Skip to content

Commit

Permalink
fixed typo in FlxG, added new function overlapsAt(), made existing ov…
Browse files Browse the repository at this point in the history
…erlaps() check able to handle tilemaps and groups better
  • Loading branch information
AdamAtomic committed Apr 28, 2011
1 parent dfd76d0 commit 31d8f34
Show file tree
Hide file tree
Showing 3 changed files with 182 additions and 21 deletions.
4 changes: 2 additions & 2 deletions org/flixel/FlxG.as
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ package org.flixel
* Assign a minor version to your library.
* Appears after the decimal in the console.
*/
static public var LIBRARY_MINOR_VERSION:uint = 50;
static public var LIBRARY_MINOR_VERSION:uint = 51;

/**
* Debugger overlay layout preset: Wide but low windows at the bottom of the screen.
Expand Down Expand Up @@ -102,7 +102,7 @@ package org.flixel
static public var paused:Boolean;
/**
* Whether you are running in Debug or Release mode.
* Set automatically by <code>FlxFactory</code> during startup.
* Set automatically by <code>FlxPreloader</code> during startup.
*/
static public var debug:Boolean;

Expand Down
100 changes: 90 additions & 10 deletions org/flixel/FlxObject.as
Original file line number Diff line number Diff line change
Expand Up @@ -664,26 +664,106 @@ package org.flixel
}

/**
* Checks to see if some <code>FlxObject</code> overlaps this <code>FlxObject</code> object in world space.
* Checks to see if some <code>FlxObject</code> overlaps this <code>FlxObject</code> or <code>FlxGroup</code>.
* If the group has a LOT of things in it, it might be faster to use <code>FlxG.overlaps()</code>.
*
* @param Object The object being tested.
* @param InScreenSpace Whether to take scroll factors into account when checking for overlap.
* @param ObjectOrGroup The object or group being tested.
* @param InScreenSpace Whether to take scroll factors into account when checking for overlap. Default is false, or "only compare in world space."
* @param Camera Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return Whether or not the two objects overlap.
*/
public function overlaps(Object:FlxObject,InScreenSpace:Boolean=false,Camera:FlxCamera=null):Boolean
public function overlaps(ObjectOrGroup:FlxBasic,InScreenSpace:Boolean=false,Camera:FlxCamera=null):Boolean
{
if(ObjectOrGroup is FlxGroup)
{
var results:Boolean = false;
var i:uint = 0;
var members:Array = (ObjectOrGroup as FlxGroup).members;
while(i < length)
{
if(overlaps(members[i++],InScreenSpace,Camera))
results = true;
}
return results;
}

if(ObjectOrGroup is FlxTilemap)
{
//Since tilemap's have to be the caller, not the target, to do proper tile-based collisions,
// we redirect the call to the tilemap overlap here.
return (ObjectOrGroup as FlxTilemap).overlaps(this,InScreenSpace,Camera);
}

var object:FlxObject = ObjectOrGroup as FlxObject;
if(!InScreenSpace)
return (Object.x + Object.width > x) && (Object.x < x + width) &&
(Object.y + Object.height > y) && (Object.y < y + height);
{
return (object.x + object.width > x) && (object.x < x + width) &&
(object.y + object.height > y) && (object.y < y + height);
}

if(Camera == null)
Camera = FlxG.camera;
var objectScreenPos:FlxPoint = Object.getScreenXY(null,Camera);
var objectScreenPos:FlxPoint = object.getScreenXY(null,Camera);
getScreenXY(_point,Camera);
return (objectScreenPos.x + Object.width > _point.x) && (objectScreenPos.x < _point.x + width) &&
(objectScreenPos.y + Object.height > _point.y) && (objectScreenPos.y < _point.y + height);
return (objectScreenPos.x + object.width > _point.x) && (objectScreenPos.x < _point.x + width) &&
(objectScreenPos.y + object.height > _point.y) && (objectScreenPos.y < _point.y + height);
}

/**
* Checks to see if this <code>FlxObject</code> were located at the given position, would it overlap the <code>FlxObject</code> or <code>FlxGroup</code>?
* This is distinct from overlapsPoint(), which just checks that point, rather than taking the object's size into account.
*
* @param X The X position you want to check. Pretends this object (the caller, not the parameter) is located here.
* @param Y The Y position you want to check. Pretends this object (the caller, not the parameter) is located here.
* @param ObjectOrGroup The object or group being tested.
* @param InScreenSpace Whether to take scroll factors into account when checking for overlap. Default is false, or "only compare in world space."
* @param Camera Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return Whether or not the two objects overlap.
*/
public function overlapsAt(X:Number,Y:Number,ObjectOrGroup:FlxBasic,InScreenSpace:Boolean=false,Camera:FlxCamera=null):Boolean
{
if(ObjectOrGroup is FlxGroup)
{
var results:Boolean = false;
var basic:FlxBasic;
var i:uint = 0;
var members:Array = (ObjectOrGroup as FlxGroup).members;
while(i < length)
{
if(overlapsAt(X,Y,members[i++],InScreenSpace,Camera))
results = true;
}
return results;
}

if(ObjectOrGroup is FlxTilemap)
{
//Since tilemap's have to be the caller, not the target, to do proper tile-based collisions,
// we redirect the call to the tilemap overlap here.
//However, since this is overlapsAt(), we also have to invent the appropriate position for the tilemap.
//So we calculate the offset between the player and the requested position, and subtract that from the tilemap.
var tilemap:FlxTilemap = ObjectOrGroup as FlxTilemap;
return tilemap.overlapsAt(tilemap.x - (X - x),tilemap.y - (Y - y),this,InScreenSpace,Camera);
}

var object:FlxObject = ObjectOrGroup as FlxObject;
if(!InScreenSpace)
{
return (object.x + object.width > X) && (object.x < X + width) &&
(object.y + object.height > Y) && (object.y < Y + height);
}

if(Camera == null)
Camera = FlxG.camera;
var objectScreenPos:FlxPoint = object.getScreenXY(null,Camera);
_point.x = X - int(Camera.scroll.x*scrollFactor.x); //copied from getScreenXY()
_point.y = Y - int(Camera.scroll.y*scrollFactor.y);
_point.x += (_point.x > 0)?0.0000001:-0.0000001;
_point.y += (_point.y > 0)?0.0000001:-0.0000001;
return (objectScreenPos.x + object.width > _point.x) && (objectScreenPos.x < _point.x + width) &&
(objectScreenPos.y + object.height > _point.y) && (objectScreenPos.y < _point.y + height);
}

/**
Expand Down Expand Up @@ -737,7 +817,7 @@ package org.flixel
Point = new FlxPoint();
if(Camera == null)
Camera = FlxG.camera;
Point.x = x - int(Camera.scroll.x*scrollFactor.x); //copied from getScreenXY()
Point.x = x - int(Camera.scroll.x*scrollFactor.x);
Point.y = y - int(Camera.scroll.y*scrollFactor.y);
Point.x += (Point.x > 0)?0.0000001:-0.0000001;
Point.y += (Point.y > 0)?0.0000001:-0.0000001;
Expand Down
99 changes: 90 additions & 9 deletions org/flixel/FlxTilemap.as
Original file line number Diff line number Diff line change
Expand Up @@ -793,9 +793,81 @@ package org.flixel
*
* @return Whether or not the two objects overlap.
*/
override public function overlaps(Object:FlxObject,InScreenSpace:Boolean=false,Camera:FlxCamera=null):Boolean
override public function overlaps(ObjectOrGroup:FlxBasic,InScreenSpace:Boolean=false,Camera:FlxCamera=null):Boolean
{
return overlapsWithCallback(Object);
if(ObjectOrGroup is FlxGroup)
{
var results:Boolean = false;
var basic:FlxBasic;
var i:uint = 0;
var members:Array = (ObjectOrGroup as FlxGroup).members;
while(i < length)
{
basic = members[i++] as FlxBasic;
if(basic is FlxObject)
{
if(overlapsWithCallback(basic as FlxObject))
results = true;
}
else
{
if(overlaps(basic,InScreenSpace,Camera))
results = true;
}
}
return results;
}
else if(ObjectOrGroup is FlxObject)
return overlapsWithCallback(ObjectOrGroup as FlxObject);
return false;
}

/**
* Checks to see if this <code>FlxObject</code> were located at the given position, would it overlap the <code>FlxObject</code> or <code>FlxGroup</code>?
* This is distinct from overlapsPoint(), which just checks that point, rather than taking the object's size into account.
* WARNING: Currently tilemaps do NOT support screen space overlap checks!
*
* @param X The X position you want to check. Pretends this object (the caller, not the parameter) is located here.
* @param Y The Y position you want to check. Pretends this object (the caller, not the parameter) is located here.
* @param ObjectOrGroup The object or group being tested.
* @param InScreenSpace Whether to take scroll factors into account when checking for overlap. Default is false, or "only compare in world space."
* @param Camera Specify which game camera you want. If null getScreenXY() will just grab the first global camera.
*
* @return Whether or not the two objects overlap.
*/
override public function overlapsAt(X:Number,Y:Number,ObjectOrGroup:FlxBasic,InScreenSpace:Boolean=false,Camera:FlxCamera=null):Boolean
{
if(ObjectOrGroup is FlxGroup)
{
var results:Boolean = false;
var basic:FlxBasic;
var i:uint = 0;
var members:Array = (ObjectOrGroup as FlxGroup).members;
while(i < length)
{
basic = members[i++] as FlxBasic;
if(basic is FlxObject)
{
_point.x = X;
_point.y = Y;
if(overlapsWithCallback(basic as FlxObject,null,false,_point))
results = true;
}
else
{
if(overlapsAt(X,Y,basic,InScreenSpace,Camera))
results = true;
}
}
return results;
}
else if(ObjectOrGroup is FlxObject)
{
_point.x = X;
_point.y = Y;
return overlapsWithCallback(ObjectOrGroup as FlxObject,null,false,_point);
}
return false;
}

/**
Expand All @@ -806,16 +878,25 @@ package org.flixel
* @param Object The <code>FlxObject</code> you are checking for overlaps against.
* @param Callback An optional function that takes the form "myCallback(Object1:FlxObject,Object2:FlxObject)", where Object1 is a FlxTile object, and Object2 is the object passed in in the first parameter of this method.
* @param FlipCallbackParams Used to preserve A-B list ordering from FlxObject.separate() - returns the FlxTile object as the second parameter instead.
* @param Position Optional, specify a custom position for the tilemap (useful for overlapsAt()-type funcitonality).
*
* @return Whether there were overlaps, or if a callback was specified, whatever the return value of the callback was.
*/
public function overlapsWithCallback(Object:FlxObject,Callback:Function=null,FlipCallbackParams:Boolean=false):Boolean
public function overlapsWithCallback(Object:FlxObject,Callback:Function=null,FlipCallbackParams:Boolean=false,Position:FlxPoint=null):Boolean
{
var results:Boolean = false;

var X:Number = x;
var Y:Number = y;
if(Position != null)
{
X = Position.x;
Y = Position.y;
}

//Figure out what tiles we need to check against
var selectionX:int = FlxU.floor((Object.x - x)/_tileWidth);
var selectionY:int = FlxU.floor((Object.y - y)/_tileHeight);
var selectionX:int = FlxU.floor((Object.x - X)/_tileWidth);
var selectionY:int = FlxU.floor((Object.y - Y)/_tileHeight);
var selectionWidth:uint = selectionX + (FlxU.ceil(Object.width/_tileWidth)) + 1;
var selectionHeight:uint = selectionY + FlxU.ceil(Object.height/_tileHeight) + 1;

Expand All @@ -835,8 +916,8 @@ package org.flixel
var column:uint;
var tile:FlxTile;
var overlapFound:Boolean;
var deltaX:Number = x - last.x;
var deltaY:Number = y - last.y;
var deltaX:Number = X - last.x;
var deltaY:Number = Y - last.y;
while(row < selectionHeight)
{
column = selectionX;
Expand All @@ -846,8 +927,8 @@ package org.flixel
tile = _tileObjects[_data[rowStart+column]] as FlxTile;
if(tile.allowCollisions)
{
tile.x = x+column*_tileWidth;
tile.y = y+row*_tileHeight;
tile.x = X+column*_tileWidth;
tile.y = Y+row*_tileHeight;
tile.last.x = tile.x - deltaX;
tile.last.y = tile.y - deltaY;
if(Callback != null)
Expand Down

0 comments on commit 31d8f34

Please sign in to comment.