/**
* @author Inateno / http://inateno.com / http://dreamirl.com
*/
/**
* @constructor OrientedBoxCollider
* @class <b>Work In Progress don't use it</b><br>
* make an oriented box Collider that follow your gameObject rotations
* @augments Collider
* @param {int} width - box width
* @param {int} height - box height
* @param {object} params - Optional parameters (offets)
* @example // classic GameObject declaration
* var myObject = new DE.GameObject( {
* x: 150, y: 200,
* collider: new DE.OrientedBoxCollider( 150, 100 )
* } );
* @example // adding a collider later
* myObject.collider = new DE.OrientedBoxCollider( 150, 100 );
*/
define( [ 'DE.Collider', 'DE.CONFIG', 'DE.CanvasBuffer', 'DE.COLORS' ],
function( Collider, CONFIG, CanvasBuffer, COLORS )
{
function OrientedBoxCollider( width, height, params )
{
params = params || {};
params.type = CONFIG.COLLISION_TYPE.ORIENTED_BOX;
Collider.call( this, params );
var _points = new Array();
var _inCircles = new Array();
var _extCircle = { x: this.localPosition.x, y: this.localPosition.y, radius: undefined };
this.width = width || 1;
this.height = height || 1;
var _left = -this.width * 0.5
, _right = this.width * 0.5
, _top = -this.height * 0.5
, _bottom = this.height * 0.5;
this.init = function()
{
_points.push( { x: _left, y: _top } );
_points.push( { x: _left, y: _bottom } );
_points.push( { x: _right, y: _bottom } );
_points.push( { x: _right, y: _top } );
for (var i = 0, p; p = _points[i]; i++)
{
p.ox = p.x;
p.oy = p.y;
}
var valx = this.localPosition.x - (this.localPosition.x + _points[0].x);
valx *= valx;
var valy = this.localPosition.y - (this.localPosition.y + _points[0].y);
valy *= valy;
_extCircle.radius = Math.sqrt( valx + valy );
var inRadius = this.width * 0.5;
_inCircles.push( { "x": 0, "y": 0, "radius": inRadius, "isColliding": false } );
if ( this.height < this.width )
{
inRadius = this.height * 0.5;
_inCircles[0] = { "x": 0, "y": 0, "radius": inRadius, "isColliding": false };
}
// generate _inCircles
var nIn = ( this.width - inRadius * 2 ) / ( inRadius * 2 ) / 2;
var horizontal = true;
if ( nIn <= 0 )
{
nIn = ( this.height - inRadius * 2 ) / ( inRadius * 2 ) / 2;
horizontal = false;
}
if ( nIn > 0 )
{
nIn >>= 0;
nIn++;
while ( nIn > 0 )
{
if ( horizontal )
{
_inCircles.push( { "x": -inRadius + _left + (inRadius * 2 * nIn), "y": 0, "radius": inRadius, "isColliding": false } );
_inCircles.push( { "x": inRadius - _left - (inRadius * 2 * nIn), "y": 0, "radius": inRadius, "isColliding": false } );
}
else
{
_inCircles.push( { "x": 0, "y": -inRadius + _top + (inRadius * 2 * nIn), "radius": inRadius, "isColliding": false } );
_inCircles.push( { "x": 0, "y": inRadius - _top - (inRadius * 2 * nIn), "radius": inRadius, "isColliding": false } );
}
nIn--;
}
}
if ( CONFIG.DEBUG_LEVEL > 1 )
this.createDebugRenderer();
}
this.createDebugRenderer = function()
{
// DEBUG level ?
// if ( CONFIG.DEBUG_LEVEL > 1 )
// {
this.debugBuffer = new CanvasBuffer( _extCircle.radius, _extCircle.radius );
this.debugBuffer.ctx.lineWidth = 2;
this.debugBuffer.ctx.strokeStyle = COLORS.DEBUG.COLLIDER;
this.debugBuffer.ctx.strokeRect( 0, 0, this.width, this.height);
// if ( CONFIG.DEBUG_LEVEL > 1 )
// {
// cercle circonscri
this.debugBuffer.ctx.strokeStyle = "blue";
this.debugBuffer.ctx.beginPath();
this.debugBuffer.ctx.arc(this.localPosition.x, this.localPosition.y, _extCircle.radius, 0, Math.PI*2, true);
this.debugBuffer.ctx.stroke();
this.debugBuffer.ctx.closePath();
// cercles inscrits
for (var i = 0, c; c = _inCircles[i]; i++)
{
this.debugBuffer.ctx.strokeStyle = "blue";
if (this.isColliding)
this.debugBuffer.ctx.strokeStyle = "green";
this.debugBuffer.ctx.beginPath();
this.debugBuffer.ctx.arc(this.localPosition.x + c.x, this.localPosition.y + c.y, c.radius, 0, Math.PI*2, true);
this.debugBuffer.ctx.stroke();
this.debugBuffer.ctx.closePath();
}
for ( var i = 0, p; p = _points[i]; i++ )
{
this.debugBuffer.ctx.strokeStyle = "red";
this.debugBuffer.ctx.fillRect( p.x-1, p.y-1, 2, 2 );
}
// }
}
this.debugRender = function( ctx )
{
ctx.rotate( -this.gameObject.position.rotation );
ctx.drawImage( this.debugBuffer.canvas
, this.localPosition.x - this.debugBuffer.canvas.width * 0.5 >> 0
, this.localPosition.y - this.debugBuffer.canvas.height * 0.5 >> 0 );
ctx.rotate( this.gameObject.position.rotation );
}
this.getExternCircle = function()
{
return _extCircle;
}
this.getInternCircles = function()
{
return _inCircles;
}
this.init();
};
OrientedBoxCollider.prototype = new Collider();
OrientedBoxCollider.prototype.constructor = OrientedBoxCollider;
OrientedBoxCollider.prototype.supr = Collider.prototype;
OrientedBoxCollider.prototype.DEName = "OrientedBoxCollider";
CONFIG.debug.log( "OrientedBoxCollider loaded", 3 );
return OrientedBoxCollider;
} );