清风明月

类别



友情链接

回复更新

计数器

日历

Flash关于不规则碰撞的一个初步解决方法

Author: PublishTime:2006-2-7

在Flash游戏中比较令人头疼的是对于元件的碰撞没有好的办法,因为对于不规则元件的判断是判断其外框是否与对方元件外框接触,而不是真实的对不规则边界的判断.下面我给的初步解决方法也没有完整地解决上述问题,否则MM早做啦还用等我来说?
之所以说是初步,是指通过下面的方法可以初步判定一个规则的元件对于不规则元件的碰撞.对此我写了一个方法hitTest2,用来进入判断.其核心源于hitTest对点的碰撞判断是可以不规则的:hitTest(x,y,flag).方法描述如下:
方法:
MovieClip.hitTest2(obj:MovieCLip[,points:Array]):Boolean
参数:
obj:待检查的影片剪辑
points:可选参数,是一个二维数组,标记obj中的点,如果缺少此参数则判断obj的四边.
返回:一个布尔值,如果与obj碰撞则返回true,否则返回false;

说明:调用此方法的影片剪辑可以是不规则的图形,而参数obj则是规则的,也可以是不规则的,但这时需要在points中指明待检测的坐标点(相对于obj本身的坐标系).

原理:通过检测obj上特定的点(中点,四边框顶点或points指明的点)来判断是否与目标碰撞.points是一个二维数组,每行包含两个元素,points[i][0]为横坐标,points[i][1]为纵坐标.

源代码如下,将源代码复制到主场景第一帧或者直接include到第一帧,直接调用hitTest2即可:
程序代码: [ 复制代码到剪贴板 ]
MovieClip.prototype.hitTest2=function(obj:MovieClip,points:Array):Boolean{
var pos:Object=obj.getBounds(_root);
//posX,posY是图形的几何中心.
var posX:Number=(pos.xMin+pos.xMax)/2;
var posY:Number=(pos.yMin+pos.yMax)/2;
//如果碰撞到中心,则返回true;
if(this.hitTest(posX,posY,true))
return true;
if(points!=undefined){//如果有传入数组.
var tmpFlag:Boolean=false;
for(var i in points){
if(this.hitTest((points[i][0]+posX),(points[i][1]+posY),true)){
tmpFlag=true;//如果目标与数组中任一坐标碰撞则返回true;
break;
}
}
return tmpFlag;
}
//如果与四边碰撞则返回true;
if(this.hitTest(pos.xMin,pos.yMin,true)||this.hitTest(pos.xMax,pos.yMin,true)||this.hitTest(pos.xMax,pos.yMax,true)||this.hitTest(pos.xMin,pos.yMax,true))
return true;
return false;
};


此方法不限影片剪辑本身的层级,因为是用getBounds(_root)来得到相对于主场景的最大/最小位置的.

例子,将下面代码复制到主场景第一帧,并新建两个元件wall,o.其中wall是不规则的,分别命名为wall,o.运行:
程序代码: [ 复制代码到剪贴板 ]
setInterval(test,50);
var x:Number=3;
var y:Number=3;
var p:Array=[[5,5],[-5,-5]];
function test(){
o._x+=x;
o._y+=y;
if(wall.hitTest2(o,p)){
trace("hit");
x=-x+2*(Math.random()-0.5);
y=-y+2*(Math.random()-0.5);
分类于:flash

Comments

{CommentAuthor} at {CommentTime} | {CommentEmail} {CommentUrl} {CommentIp}
{CommentContent}
Powered by 5DBlog.com