Much people asking about how to manage collision in isometric.
The eassy way is using ordinary coordinate system (everybody already familiar with it) and do project - unproject, using a matrix, to show on screen.
The Isometric coordinate system is:
- ordinary cartessian system
- rotate it 45 degree
- scale the y to whatever you want. Usually 0.5
So we can create a projection matrix like this:
public function updateProjectionMatrix(tileSquare:Number, yScale:Number):void
{
// Assumed: tile width = tile height = tileSquare
var tLength:Number = Math.sqrt(tileSquare * tileSquare * 2);
projectionMatrix = new Matrix();
projectionMatrix.translate(-tileSquare/2, -tileSquare/2);
projectionMatrix.rotate(45 * Math.PI/180);
projectionMatrix.scale(tileSquare/tLength, tileSquare * yScale/tLength);
// We also prepare a matrix for unprojection:
unprojectionMatrix = projectionMatrix.clone();
unprojectionMatrix.invert();
}
Another way is by defining the tile's dimension:
public function updateProjectionMatrix(tileWidth:Number, tileHeight:Number):void
{
var tLength:Number = Math.sqrt(tileWidth * tileWidth + tileHeight * tileHeight);
projectionMatrix = new Matrix();
projectionMatrix.translate(-tileWidth/2, -tileWidth/2);
projectionMatrix.rotate(45 * Math.PI/180);
projectionMatrix.scale(tileWidth/tLength, tileHeight/tLength);
// We also prepare a matrix for unprojection:
unprojectionMatrix = projectionMatrix.clone();
unprojectionMatrix.invert();
}
Having those matrices making the collision handling more easy.
For example:
If you have more than 1 DisplayObject and wants to recognize the collission
try it:
- put originPosition as property
- put isoPosition as property
in your IsometricObject
public static function isCollide(objA:IsometricObject, objB:IsometricObject):Boolean
{
return objA.getOriginBound().intersects(objB.getOriginBound());
}
Of course you need a getOriginBound() function.
// Assumed you put the graphics in center:
public function getOriginBound():Rectangle
{
return new Rectangle(this.originPosition.x - this.originWidth/2,
this.originPosition.y - this.originHeight/2,
this.originWidth,
this.originHeight);
}
This is the complete IsometricObject for a base object to extends:
package
{
import flash.display.MovieClip;
import flash.geom.Point;
import flash.geom.Rectangle;
public class IsometricObject extends MovieClip
{
public var originPosition:Point = new Point();
public var isoPoint:Point;
public var originWidth:Number;
public var originHeight:Number;
public function IsometricObject(ox:Number=0, oy:Number=0, ow:number=0, oh:Number=0)
{
originWidth = ow;
originHeight = oh;
setOrigin(ox, oy);
}
public function setOrigin(xx:Number, yy:Number):void
{
originPosition.x = xx;
originPosition.y = yy;
isoPoint = MyIsoEngine.project(originPosition);
}
}
}
You also create an MyIsoEngine by including these:
package
{
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import IsometricObject;
public class MyIsoEngine
{
public static var tileWidth:Number;
public static var tileHeight:Number;
public static var projectionMatrix:Matrix;
public static var unprojectionMatrix:Matrix;
public static function project(p:Point):Point
{
return projectionMatrix.transformPoint(p);
}
public static function unproject(p:Point):Point
{
return unprojectionMatrix.transformPoint(p);
}
public static function isCollide(objA:IsometricObject, objB:IsometricObject):Boolean
{
return objA.getOriginBound().intersects(objB.getOriginBound());
}
// Initing the engine requires at least:
public static function initEngine(tileW:Number, tileH:Number):void
{
tileWidth = tileW;
tileHeight = tileH;
updateProjectionMatrix();
}
protected static function updateProjectionMatrix():void
{
var tLength:Number = Math.sqrt(tileWidth * tileWidth + tileHeight * tileHeight);
projectionMatrix = new Matrix();
projectionMatrix.translate(-tileWidth/2, -tileWidth/2);
projectionMatrix.rotate(45 * Math.PI/180);
projectionMatrix.scale(tileWidth/tLength, tileHeight/tLength);
// We also prepare a matrix for unprojection:
unprojectionMatrix = projectionMatrix.clone();
unprojectionMatrix.invert();
}
}
}
easy?....
yeah!
See my engine at http://www.icesflash.com/iso.index.html