关于多对多影片的碰撞检测解决办法

不知道大家在编写脚本的时候有没有遇到这样的一种情况呢?有一个影片实例是要对另一个影片实例进行碰撞检测,但是这两个影片实例都是用attachMovie语句或者用duplicateMovieClip语句复制到场景中的,并且两个影片实例的复制个数都大于一个。如果觉得我这样说不够清楚的话,那么我拿一个射击游戏来说好了,就好像飞机的子弹要和敌人进行碰撞检测来确定是否击中敌人,但是这时候的子弹和敌人都是用影片复制出来的,那么我们应该怎么样来检测敌人和子弹是否击中呢?我把它称为多对多的影片检测。
    如果你现在直接在影片中写下对另一个影片的检测语句,那明显是行不通的。因为hitTest是针对两个物体之间的来进行检测判断的,而复制出来的影片名字又是不固定的,所以这样做并不能达到目的。也许有人说,我可以把要复制的影片全部写上检测,但这样做并不实在,如果复制的影片的数量不多时采用这种方法还可以说得过去。但是如果复制的影片的数量不固定并且是很多的时候,那么你要写的代码就可能是长篇大论了~~而且代码的冗余量也会很大。所以这种做法并不理智,下面我讲一个我自己研究出来的方法,虽然执行的效率并不是那么的好,但总能解决这个麻烦。当然如果那位高人能有更好的办法,不妨指点一下,小弟一定感激不尽!
    好!现在让我来说一下解决这个多对多影片检测问题的思路吧。
    首先,我们依然要用到hitTest这个语句来对影片进行检测,不过现在的源影片实例与目标影片实例都不是固定的。所以我们要想办法将这种多对多的影片检测转换成为一对多的影片检测(解决大问题的最好办法就是转化成为若干个小问题来解决^0^),这样,我们就能确定出一个源影片实例或者是一个目标影片实例了。那么,我们应该怎样去转化呢?我们知道如果你在影片剪辑中写下要实现某功能的脚本,那么以它为母影片复制出来的新影片剪辑也同样有此种功能。好了,知道这一点我们就可以解决这个转化问题了,只要我们把进行碰撞检测的脚本写进其中一个影片实例中,那么这样不就是可以让每一个从这个影片实例复制出来的新影片拥有了检测另一个影片实例的方法吗?
    做完上一步工作之后,现在我们的问题变成了一对多的影片检测问题了。现在,要写进hitTest语句中还有一个影片实例是不固定的,那么我们用另一个办法把这些影片实例确定下来。那么,在这里面我们用数组(Array)去把影片实例保存下来。也就是说,每复制一个新影片,就往数组里面加入这个影片实例。
    那么,接下来不用说也知道了吧。那就是在写着碰撞检测方法的影片实例中用循环分别对另一个影片复制出来的新影片进行检测。
    呵呵~~思路就这么的简单,为了让各位朋友更容易弄懂,我就在下面举一个例子吧!
    我们来新建一个影片文件(.fla),然后新建两个影片剪辑,一个名为circle,在里面画一个圆。一个名为rectangle,在里面画一个矩形。
    接着,我们为这两个影片剪辑加上链接标识符(目的是为了用attachMovie语句来进行复制)。链接的标识符可以随意,我这里与影片剪辑名称相同。现在,我们要把这个多对多问题进行转化,我们进入到circle影片里面,在第一帧上写上如下代码:
    //用来计算时间
    var stime, etime:Number;
    stime = getTimer();
    this.onEnterFrame = function() {
        etime = getTimer();
        //这里是每100毫秒执行一次检测,值越小检测就越精确,不过会影响执行效率。
        if ((etime-stime)>100) {
            Checkhit();
            stime = getTimer();
        }
        //移动影片
        this._x += 5;
    };
    //碰撞检测的函数
    function Checkhit() {
        //逐个检测objArray数组里面存储的影片实例
        for (var count in _root.objArray) {
            if (this.hitTest(_root.objArray[count])) {
                _root.objArray[count].removeMovieClip();
                _root.objArray.splice(count, 1);
                this.removeMovieClip();
            }
        }
    }

    接下来就是要在复制rectangle新影片时把它的影片实例加入到数组里面去。我们看下面的代码:
    //这是加在主场景下的脚本
    //用来标识新影片的编号
    var i:Number = 0;
    var j:Number = 0;
    //用来存放复制的影片实例的数组
    var objArray:Array = new Array();
    var startTime,endTime:Number;
    //复制circle影片
    function CpCircle() {
       _root.attachMovie("circle", "circle"+i, _root.getNextHighestDepth());
       _root["circle"+i]._x = 0;
       _root["circle"+i]._y = 100;
       i++;
    }
    //复制rectangle影片
    function CpRectangle() {
       var temp:MovieClip;
       temp=_root.attachMovie("rectangle", "rectangle"+j, _root.getNextHighestDepth());
       temp._x = 550;
       temp._y = 100;
       j++;
       //把新影片对象加入到数组里面
       objArray=objArray.concat(temp);
    }
    startTime=getTimer();
    _root.onEnterFrame=function (){
        endTime=getTimer();
       //每秒复制一次影片
       if((endTime-startTime)>1000){
          CpCircle();
          CpRectangle();
          startTime=getTimer();
       }
    }

    为了看出效果来,我们也让rectangle影片的实例动起来,我们进入到rectangle影片里面,加入下面的代码:
    this.onEnterFrame=function(){
         this._x-=5;
    }

    我们可以按Ctrl+Enter来测试一下,问题是不是解决了呢?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值