Properties  Methods  Examples  Index
Package com.coreyoneil.collision
Class public class CollisionGroup
Inheritance CollisionGroup —> CDK —> Object

Language Version: Actionscript 3.0
Player Version: Flash Player 9

The CollisionGroup class lets you perform pixel-precise (shape-based) collision detections for display objects in a many/many relationship. All display objects added to a collision group will check for collisions with each other. CollisionGroup works with all display objects, including MovieClips, Sprites, Bitmaps, TextFields, and FLVs.

BitmapData is generated for display objects inside a collision group instance. This data is then used to find any overlapping objects on the stage. This is performed using logic extended from the CDK class.

CollisionGroup accounts for transformations (scale, rotation, color transforms, etc.) made to instances of objects. It can return the angle of collision between two objects based on their shapes where the collision occurred, and tell you how much overlap there is between the two objects.

CollisionGroup is unique from its sister class CollisionList in that it will check for collisions against all of its children. For example, if you had four display objects in a collision group - let's call them A, B, C, and D - and checked for collisions, there would be six collision checks made:

At least two display objects must be added to a collision group before you may check for collisions. Display objects that you no longer want to check against for collisions can be removed from a collision list using the removeItem() method.


Public Properties

Property Defined By
alphaThreshold : Number
A floating point value from 0 to 1 that determines the minimum alpha value to check for collisions.
CDK
numChildren : uint
[read-only] Returns the number of display objects in the collision group.
CDK
returnAngle : Boolean
If set to true, CollisionGroup will return an approximated angle of each collision that's detected.
CDK
returnAngleType : String
A value that determines if the angle returned from a collision is in degrees or radians.
CDK


Public Methods

Method Defined By
CollisionGroup(... objs)
Creates a CollisionGroup object with optional display object parameters.
CollisionGroup
addItem(obj:DisplayObject)
Adds a display object to the collision group's list of objects to check for collisions.
CDK
checkCollisions():Array
Takes every possible pairing of display objects in the collision group and checks for collisions. If a pair of objects have collided, they are recorded and returned by checkCollisions() as an array.
CollisionGroup
excludeColor(theColor:uint, alphaRange:uint = 0, redRange:uint = 0, greenRange:uint = 0, blueRange:uint = 0)
Defines a color or color range to exclude from collision detections. The excludeColor() method expects a 32 bit color value. Optional ranges based on this color can be specified for all channels using the additional parameters.
CDK
removeExcludeColor(theColor:uint)
Removes the color specified from the list of colors to exclude from collision detections. Expects a 32 bit color value.
CDK
removeItem(obj:DisplayObject)
Removes the specified display object from the collision group.
CDK



Property Detail


alphaThreshold  property
alphaThreshold:Number [read-write]

A floating point value from 0 to 1 that determines the minimum alpha value to check for collisions. The default setting is 0.

If alphaThreshold were set to .5, then CollisionGroup would ignore any collisions that occurred where either of the display objects' overlapping pixels had an alpha equal to or below .5

View an Example

Implementation
     public function get alphaThreshold():Number
     public function set alphaThreshold(theAlpha:Number)

numChildren  property
numChildren:uint [read-only]

Returns the number of display objects in the collision group.

Implementation
     public function get numChildren():uint

returnAngle  property
returnAngle:Boolean [read-write]

If set to true, CollisionGroup will return an approximated angle of each collision that's detected. The default setting is false.

The angle of collision for each collision is returned by the checkCollisions() method.

Implementation
     public function get returnAngle():Boolean
     public function set returnAngle(option:Boolean)

See Also
     returnAngleType
     checkCollisions()

returnAngleType  property
returnAngleType:String [read-write]

A value that determines if the angle returned from a collision is in degrees or radians. The following values are accepted by returnAngleType (not case-sensitive):

The default setting is RADIANS.



Implementation
     public function get returnAngle():Boolean
     public function set returnAngle(option:Boolean)

See Also
     returnAngle


Method Detail


CollisionGroup()  Constructor
public function CollisionGroup(... objs)

Creates a CollisionGroup object with optional display object parameters. If you want to add display objects to the collision group during instantiation, you can pass them into the constructor. For example, if you had three display objects called A, B, and C that you wanted to add for collision detection, you could create the group like this:

var collisions:CollisionGroup = new CollisionGroup(A, B, C);

Parameters
     ... objs — Optional list of display objects to add to the collision group.

Throws
     Error — Object passed isn't a valid display object


addItem()  method
public function addItem(obj:DisplayObject):void

Adds a display object to the collision group's list of objects to check for collisions.

Parameters
     obj : DisplayObject — The display object to add to the collision group.

Throws
     Error — Object added isn't a valid display object

See Also
     removeItem()

checkCollisions()  method
public function checkCollisions():Array

Takes every possible pairing of display objects in the collision group and checks for collisions. If a pair of objects have collided, they are recorded and returned by checkCollisions() as an array.

The array returned by checkCollisions() is an array of objects representing each collision, with each object containing the following properties:

Returns
    Array — An array containing information for each collision that was recorded. Each element in the array is an object containing the two display objects
                      that collided, their angle of collision, and the overlapping points between the two display objects.


See Also
     returnAngle

excludeColor()  method
public function excludeColor(theColor:uint, alphaRange:uint = 255, redRange:uint = 20, greenRange:uint = 20, blueRange:uint = 20):void

Defines a color or color range to exclude from collision detections. The excludeColor() method expects a 32 bit color value. Optional ranges based on this color can be specified for all channels using the additional parameters. Each range accepts integral values from 0 to 255, accounting for all values for each color channel. The ranges move in both directions at the amount specified for each channel. For example, if you had a collision group named "collisions" and called excludeColor() like so:

collisions.excludeColor(0xFFCCAADD, 0, 0, 20, 0);

... then all pixels with colors between 0xFFCC95DD and 0xFFCCBDDD would be excluded from collisions. Pixels are only excluded from collisions if all four channels (ARGB) are within their respective ranges. You may exclude as many colors/ranges as you want by making multiples calls to excludeColor().

Because the Collision Detection Kit performs its detections based on pixel values, it's not uncommon for pixels on the edge of a display object to have alpha values lower than the main color of its shape. This is caused by anti-aliasing performed on the display object. Because of this, the excludeColor() method defaults its ranges so that it accounts for all alpha values, and provides a small range of 20 for red, green, and blue. This accounts for most discrepancies, allowing you to simply pass the color value you wish to exclude without needing to adjust ranges.

excludeColor() is CPU-intensive. It's suggested that you only exclude one or two colors when working with larger display objects or a large number of display objects in your collision list. Whenever possible, use alphaThreshold instead.

View an Example

Parameters
     theColor : uint — The color to exclude. Must be a 32 bit value (Example: 0xFF663322)

     alphaRange : uint (default = 255) — The integral range of alpha values to exclude, based on the color's alpha value. Valid values are 0 - 255

     redRange : uint (default = 20) — The integral range of red values to exclude, based on the color's red value. Valid values are 0 - 255

     greenRange : uint (default = 20) — The integral range of green values to exclude, based on the color's green value. Valid values are 0 - 255

     blueRange : uint (default = 20) — The integral range of blue values to exclude, based on the color's blue value. Valid values are 0 - 255

See Also
     removeExcludeColor()

removeExcludeColor()  method
public function removeExcludeColor(theColor:uint):void

Removes the color specified from the list of colors to exclude from collision detections. Must be a color previously added using the excludeColor() method. Expects a 32 bit color value.

Parameters
     theColor : uint — The color to remove from exclusions. Must be a 32 bit value (Example: 0xFF663322)

Throws
     Error — Color specified isn't in the exclusion list.

See Also
     excludeColor()

removeItem()  method
public function removeItem(obj:DisplayObject):void

Removes the specified display object from the collision group.

Parameters
     obj : DisplayObject — The display object to remove from the collision group.

Throws
     Error — Display object isn't in the collision group

See Also
     addItem()


Examples


All of the following examples make use of a simple setup to show how to make use of CollisionGroup. To run them, you will have to have downloaded the Collision Detection Kit and included it in your list of classpaths.

In this first example, CollisionGroup is used to detect collisions between four display objects. The four display objects are Sprites containing two overlaying ellipses. This was done to provide a more unique shape to better show that the collision detection is shape-based. The user can drag the shapes around the stage, and when any of them collide with each other, a text box displays which shapes collided. This task is accomplished using the following steps:

Copy and paste the code into the timeline of a new FLA and compile to see it in action.

import com.coreyoneil.collision.CollisionGroup;

var messageBox:TextField = new TextField();
addChild(messageBox);

var collisionGroup:CollisionGroup = new CollisionGroup();

for(var i:uint = 0; i < 4; i++)
{
	var shape:Sprite = new Sprite();
	shape.name = "shape " + i;
	addChild(shape);
	
	shape.graphics.beginFill(Math.random() * 0xFFFFFF);
	shape.graphics.drawEllipse(-40, -20, 80, 40);
	shape.graphics.drawEllipse(-20, -40, 40, 80);
	shape.graphics.endFill();

	shape.rotation = Math.random() * 180;
	shape.scaleX = shape.scaleY = Math.random() + .5;
	
	shape.x = stage.stageWidth / 4 * i + 40;
	shape.y = stage.stageHeight / 4 * i + 40;
	
	shape.buttonMode = true;
	
	shape.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown_Handler);
	
	collisionGroup.addItem(shape);
}

function mouseDown_Handler(e:MouseEvent):void
{
	var shape:Sprite = e.currentTarget as Sprite;
	stage.addChild(shape);
	
	e.currentTarget.startDrag();
	e.currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, checkForCollision);
	e.currentTarget.addEventListener(MouseEvent.MOUSE_UP, mouseUp_Handler);
}

function mouseUp_Handler(e:MouseEvent):void
{
	e.currentTarget.stopDrag();
	
	e.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, checkForCollision);
	e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, mouseUp_Handler);
}

function checkForCollision(e:MouseEvent):void
{
	var collisions:Array = collisionGroup.checkCollisions();
	
	messageBox.text = "";

	for(var i:uint = 0; i < collisions.length; i++)
	{
		var firstShape:Sprite = collisions[i].object1;
		var secondShape:Sprite = collisions[i].object2;
		messageBox.appendText(firstShape.name + " colliding with " + secondShape.name + "\n");
		messageBox.autoSize = "center";
		messageBox.x = stage.stageWidth / 2 - messageBox.width / 2;
	}
}


This example shows the basic usage of the alphaThreshold property. Four Sprites are created and set up so that they can be dragged over one another. Each Sprite contains two circles laying overtop one another. The inner circle is red with an alpha of 1. The larger circle is also red, with a .25 alpha value. The Sprites will ignore the lower alpha values and only detect collisions with the more opaque value. All collisions are reported via a text field. This is accomplished through the following steps:

Copy and paste the code into the timeline of a new FLA and compile to see it in action.

import com.coreyoneil.collision.CollisionGroup;

var messageBox:TextField = new TextField();
addChild(messageBox);

var collisionGroup:CollisionGroup = new CollisionGroup();

collisionGroup.alphaThreshold = .25;

for(var i:uint = 0; i < 4; i++)
{
	var shape:Sprite = new Sprite();
	shape.name = "shape " + i;
	addChild(shape);
	
	shape.graphics.beginFill(0xFF0000, .25);
	shape.graphics.drawCircle(0, 0, 40);
	shape.graphics.endFill();
	
	shape.graphics.beginFill(0xFF0000, 1);
	shape.graphics.drawCircle(0, 0, 20);
	shape.graphics.endFill();

	shape.scaleX = shape.scaleY = Math.random() + .5;
	
	shape.x = stage.stageWidth / 4 * i + 40;
	shape.y = stage.stageHeight / 4 * i + 40;
	
	shape.buttonMode = true;
	
	shape.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown_Handler);
	
	collisionGroup.addItem(shape);
}

function mouseDown_Handler(e:MouseEvent):void
{
	var shape:Sprite = e.currentTarget as Sprite;
	stage.addChild(shape);
	e.currentTarget.startDrag();
	
	e.currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, checkForCollision);
	e.currentTarget.addEventListener(MouseEvent.MOUSE_UP, mouseUp_Handler);
}

function mouseUp_Handler(e:MouseEvent):void
{
	e.currentTarget.stopDrag();
	
	e.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, checkForCollision);
	e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, mouseUp_Handler);
}

function checkForCollision(e:MouseEvent):void
{
	var collisions:Array = collisionGroup.checkCollisions();
	
	messageBox.text = "";

	for(var i:uint = 0; i < collisions.length; i++)
	{
		var firstShape:Sprite = collisions[i].object1;
		var secondShape:Sprite = collisions[i].object2;
		messageBox.appendText(firstShape.name + " colliding with " + secondShape.name + "\n");
		messageBox.autoSize = "center";
		messageBox.x = stage.stageWidth / 2 - messageBox.width / 2;
	}
}


This example shows the basic usage of the excludeColor() method. Sprites containing circles will be set up and placed in a CollisionGroup instance so that they can be dragged overtop one another. Each Sprite will contain two circles, one red and one green. The Sprites will ignore all red pixels, and only detect collisions on green. All collisions are reported via a text field. This is accomplished through the following steps:

Copy and paste the code into the timeline of a new FLA and compile to see it in action.

import com.coreyoneil.collision.CollisionGroup;

var messageBox:TextField = new TextField();
addChild(messageBox);

var collisionGroup:CollisionGroup = new CollisionGroup();

collisionGroup.excludeColor(0xFFFF0000);

for(var i:uint = 0; i < 4; i++)
{
	var shape:Sprite = new Sprite();
	shape.name = "shape " + i;
	addChild(shape);
	
	shape.graphics.beginFill(0xFF0000);
	shape.graphics.drawCircle(0, 0, 40);
	shape.graphics.endFill();
	
	shape.graphics.beginFill(0x00AA00);
	shape.graphics.drawCircle(0, 0, 20);
	shape.graphics.endFill();

	shape.scaleX = shape.scaleY = Math.random() + .5;
	
	shape.x = stage.stageWidth / 4 * i + 40;
	shape.y = stage.stageHeight / 4 * i + 40;
	
	shape.buttonMode = true;
	
	shape.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown_Handler);
	
	collisionGroup.addItem(shape);
}

function mouseDown_Handler(e:MouseEvent):void
{
	var shape:Sprite = e.currentTarget as Sprite;
	stage.addChild(shape);
	e.currentTarget.startDrag();
	
	e.currentTarget.addEventListener(MouseEvent.MOUSE_MOVE, checkForCollision);
	e.currentTarget.addEventListener(MouseEvent.MOUSE_UP, mouseUp_Handler);
}

function mouseUp_Handler(e:MouseEvent):void
{
	e.currentTarget.stopDrag();
	
	e.currentTarget.removeEventListener(MouseEvent.MOUSE_MOVE, checkForCollision);
	e.currentTarget.removeEventListener(MouseEvent.MOUSE_UP, mouseUp_Handler);
}

function checkForCollision(e:MouseEvent):void
{
	var collisions:Array = collisionGroup.checkCollisions();
	
	messageBox.text = "";

	for(var i:uint = 0; i < collisions.length; i++)
	{
		var firstShape:Sprite = collisions[i].object1;
		var secondShape:Sprite = collisions[i].object2;
		messageBox.appendText(firstShape.name + " colliding with " + secondShape.name + "\n");
		messageBox.autoSize = "center";
		messageBox.x = stage.stageWidth / 2 - messageBox.width / 2;
	}
}