AS3 - 碰撞检测,距离计算总结
Flex,flash游戏中经常用到的就是碰撞检测与距离检测了,下面列举了几种常见的情况:
2,两个圆的碰撞(即判断两个圆是否相交)
3,两个矩形的碰撞检测(使用hitTestObject函数。这个只能用于矩形,不规则的图形这个方法也是按矩形边框来检测)
4,圆与一个不规则图形的碰撞检测(在圆周上取一系列的采集点,分别进行碰撞测试)
5,一个点距一个不规则图形的距离
(以这点为圆心,半径从1开始逐步增加画圆,每个圆上取一定量的采集点与目标区域进行碰撞检测,碰撞了说明距离就是这个半径了。这个半径需要设个上限,要不然的话影响性能。)
6,一个圆距一个不规则图形的距离(原理同上,只不过探测圆的半径从检测圆的半径开始)
1,一个点与一个Sprite的碰撞(使用hitTestPoint函数即可)
wall.hitTestPoint(player.x,player.y,true);
/** * x1,y1,r1:第一个圆的x坐标,y坐标和半径 * x2,y2,r2:第二个圆的x坐标,y坐标和半径 */ private function checkCircleCollide(x1:Number, y1:Number, r1:Number, x2:Number, y2:Number, r2:Number):Boolean{ var dx:Number = x1 - x2; var dy:Number = y1 - y2; var r:Number = r1 + r2; if (dx*dx + dy*dy < r*r) { return true; //相交 }else{ return false; //不相交 } }
sprite1.hitTestObject(sprite2);
/** * 判断一个点与目标物体是否发生碰撞 * x,y,r测试圆的x坐标,y坐标,半径 */ private function checkCollide(x:Number, y:Number, r:Number, wall:Sprite):Boolean{ // 角度临时变量 var rayAngle:Number; // 精度 precision,取这个圆周上的20个测试点 var precision:Number=20; // 判断每个测试点是否与目标物体发生碰撞 for (var i:Number=0; i<=precision; i++) { // 根据精度,算出角色元件 一圈判断点的角度 rayAngle=2*Math.PI/precision*i; // 判断点是否与墙壁碰撞 if (wall.hitTestPoint(x+r*Math.cos(rayAngle),y+r*Math.sin(rayAngle),true)) { // 发现并记录该点 return true; break; } } return false; }
(以这点为圆心,半径从1开始逐步增加画圆,每个圆上取一定量的采集点与目标区域进行碰撞检测,碰撞了说明距离就是这个半径了。这个半径需要设个上限,要不然的话影响性能。)
/** * 计算一个点与目标物体的距离 * x,y测试点的x坐标,y坐标 */ private function calculateDistance(x:Number, y:Number, wall:Sprite):Number{ if(wall.hitTestPoint(x,y,true)){ return 0; } // 角度临时变量 var rayAngle:Number; // 精度 precision,取这个圆周上的20个测试点 var precision:Number=20; // 判断每个测试点是否与目标物体发生碰撞 // 半径扩大精度 var rayStep:Number=1; // 最远探测距离 var minDistance:Number=50; for (var i:Number=0; i<=precision; i++) { // 根据精度,算出角色元件 一圈判断点的角度 rayAngle=2*Math.PI/precision*i; // 逐步向外探测 for (var j:Number=1; j<=51; j+=rayStep) { // 判断点是否与墙壁碰撞 if (wall.hitTestPoint(x+j*Math.cos(rayAngle),y+j*Math.sin(rayAngle),true)) { // 发现并记录该点 minDistance=Math.min(j,minDistance); break; } } } return minDistance; }
/** * 计算一个圆 与目标物体的距离 * x,y,r测试圆 的x坐标,y坐标,半径 */ private function calculateDistance(x:Number, y:Number, r:Number, wall:Sprite):Number{ // 角度临时变量 var rayAngle:Number; // 精度 precision,取这个圆周上的20个测试点 var precision:Number=20; // 判断每个测试点是否与目标物体发生碰撞 // 半径扩大精度 var rayStep:Number=1; // 最远探测距离 var minDistance:Number=50; for (var i:Number=0; i<=precision; i++) { // 根据精度,算出角色元件 一圈判断点的角度 rayAngle=2*Math.PI/precision*i; // 逐步向外探测 for (var j:Number=r; j<=r+50; j+=rayStep) { // 判断点是否与墙壁碰撞 if (wall.hitTestPoint(x+j*Math.cos(rayAngle),y+j*Math.sin(rayAngle),true)) { // 发现并记录该点 minDistance=Math.min(j-r,minDistance); break; } } } return minDistance; }