基于网格的碰撞检测
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;
}
}
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;
}
}
相关文章推荐
- 基于cocos2d-x对俯视角游戏碰撞检测及碰撞处理的探究
- Ogre 中基于蒙皮骨骼的OBB碰撞检测
- 基于分离轴定理的碰撞检测
- 基于投影方法的碰撞检测以及一个测试DEMO【C + SDL】
- 从零开始做一个基于pygame引擎的躲闪小游戏(一)-画矩形、画圆、简单的碰撞检测
- (译)碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分
- 基于2D多边形的碰撞检测和响应(七)
- 笔记:基于距离的多物体碰撞检测
- Ogre碰撞检测,精确到物体网格三角面
- 基于cocos2d-x的2D空间中的OBB(Orient Bounding Box)碰撞检测算法
- 基于 HTML5 Canvas 的 3D 碰撞检测
- (译)碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分
- GameUnity 2.0 文档(四) 网格+四叉树 最优碰撞检测
- 基于HTML5及WebGL开发的2D3D第一人称漫游进行碰撞检测
- 基于2D多边形的碰撞检测和响应(三)
- [译]在Tiled Map中使用碰撞检测(一) 创建基于Tiled Map的游戏
- [译]在Tiled Map中使用碰撞检测(一) 创建基于Tiled Map的游戏
- 11. 碰撞检测和收集物品:如何使用cocos2d制作基于tiled地图的游戏:第二部分
- [OpenGL]基于AABB包围盒的漫游时视点与场景的碰撞检测