Source: extended/OrientedBoxCollider.js

/**
 * @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;
} );
Dreamirl Copyright © 2014 And the contributors
Documentation generated by JSDoc 3.2.2 on Thu Apr 24 2014 11:56:40 GMT+0200 (CEST) using the DocStrap template.