您的位置:首页 > 其它

基于网格的碰撞检测

2012-03-09 18:54 363 查看
1)碰撞检测有两种常用方法:将所有物件两两测试,当物件数量少的时候,用这种方式既简单又快速; 基于网格检测,先将整个区域划分成格子,再基于格子检测,遍历所有格式,先检查本格中的所有物件,再将本格和相邻格中的物件一一检测,当物件数量多时,需要用这种方式进行检测,将大大减少检测数量;

2)划分格式时,应确保格子的尺寸比“最大的物件”尺寸还要大,必须能保证格式一定能将物件包住;

3)每个格子在检测时,只用检测“右边”、”左下边“、”下边“、”右下边“这四个格子就行,不用检测周边的八个格子;

4) 用一维数组来保存格子,通过在索引上做文章来识别它以属于第几行,这样能提高性能。

==========================================

private function checkGrid(): void

{

for(var i: int=0; i < _grid.length; i++)

{

for(var j: int=0; j < _grid[ i ].length; j++)

{

// 检测第一个格子内的对象间是否发生碰撞

checkOneCell(i, j);

checkTwoCells(i, j, i+1, j); // 右边的格子

checkTwoCells(i, j, i-1, j+1); // 左下角的格子

checkTwoCells(i, j, i, j+1); // 下边的格子

checkTwoCells(i, j, i+1, j+1); // 右下角的格子

}

}

}

private function checkOneCell(x: int, y: int): void

{

// 检测当前格子内所有的对象

var cell:Array = _grid[ x ][ y ] as Array;

for(var i: int=0; i < cell.length-1; i++)

{

var ballA: Ball = cell[ i ] as Ball;

for(var j: int=i+1; j < cell.length; j++)

{

var ballB: Ball = cell[ j ] as Ball;

checkCollision(ballA, ballB);

}

}

}

private function checkTwoCells(x1: int, y1: int, x2: int, y2: int): void

{

// 确保要检测的格子存在

if(x2 < 0) return;

if(x2 >= _grid.length) return;

if(y2 >= _grid[ x2 ].length) return;

var cell0:Array = _grid[ x1 ][ y1 ] as Array;

var cell1:Array = _grid[ x2 ][ y2 ] as Array;

// 检测当前格子和邻接格子内所有的对象

for(var i: int=0; i < cell0.length; i++)

{

var ballA: Ball = cell0[ i ] as Ball;

for(var j: int=0; j < cell1.length; j++)

{

var ballB: Ball = cell1[ j ] as Ball;

checkCollision(ballA, ballB);

}

}

}

private function checkCollision(ballA: Ball, ballB: Ball):void

{

// 判断距离的碰撞检测

_numChecks++;

var dx: Number = ballB.x - ballA.x;

var dy: Number = ballB.y - ballA.y;

var dist: Number = Math.sqrt(dx * dx + dy * dy);

if(dist < ballA.radius + ballB.radius)

{

ballA.color = 0xff0000;

ballB.color = 0xff0000;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: