JavaScript碰撞检测

JavaScript碰撞检测主要用于游戏开发等。几乎所有的游戏都离不开碰撞检测——无论是各物体之间的碰撞检测,还是物体与场景之间的碰撞检测。

代码如下:

    <style>
        div.divtest{
            width:500px;
            height:300px;
            border:1px solid black;
            position:relative;
        }
        div.divtest div:first-child{
            width:50px;
            height:50px;
            background-color:red;
            position:absolute;
            top:0;
            left:0;
        }
        div.divtest div:last-child{
            width:50px;
            height:50px;
            background-color:blue;
            position:absolute;
            top:250px;
            left:450px;
        }
    </style>
    <div class="divtest">
        <div></div>
        <div></div>
    </div>
    <script>
        var div=document.querySelector(".divtest");
        var box1=document.querySelector(".divtest div:first-child");
        var box2=document.querySelector(".divtest div:last-child");
        var dir1_l=true,dir1_t=true,dir2_l=false,dir2_t=false;//定义盒子的运动方向
        var speed1_l=5,speed1_t=3,speed2_l=3,speed2_t=6; //定义盒子各个方向的运动速度
        var divw,divh,boxw,boxh,box1_l,box1_t,box2_l,box2_t;//定义盒子的各个属性值
        //检测浏览器获取样式(主要为了兼容IE)
        if(div.currentStyle){
            divw=parseInt(wrap.currentStyle.width);
            divh=parseInt(wrap.currentStyle.height);
            boxw=parseInt(box1.currentStyle.width);
            boxh=parseInt(box1.currentStyle.height);
            box1_l=parseInt(box1.currentStyle.left);
            box1_t=parseInt(box1.currentStyle.top);
            box2_l=parseInt(box2.currentStyle.left);
            box2_t=parseInt(box1.currentStyle.top);
        }else{
            divw=parseInt(getComputedStyle(div,[]).width);
            divh=parseInt(getComputedStyle(div,[]).height);
            boxw=parseInt(getComputedStyle(box1,[]).width);
            boxh=parseInt(getComputedStyle(box1,[]).height);
            box1_l=parseInt(getComputedStyle(box1,[]).left);
            box1_t=parseInt(getComputedStyle(box1,[]).top);
            box2_l=parseInt(getComputedStyle(box2,[]).left);
            box2_t=parseInt(getComputedStyle(box2,[]).top);
        }

        setInterval(function(){
            //动态获取盒子的属性值
            if(box1.style.left){
                box1_l=parseInt(box1.style.left);
                box1_t=parseInt(box1.style.top);
                box2_l=parseInt(box2.style.left);
                box2_t=parseInt(box2.style.top);
            }
            //判断box分别碰到边框的情况,改变其方向
            if(box1_l<=0){
                dir1_l=true;
            }else if(box1_l>=divw-boxw){
                dir1_l=false;
            }
            if(box2_l<=0){
                dir2_l=true;
            }else if(box2_l>=divw-boxw){
                dir2_l=false;
            }
            if(box1_t<=0){
                dir1_t=true;
            }else if(box1_t>=divh-boxh){
                dir1_t=false;
            }
            if(box2_t<=0){
                dir2_t=true;
            }else if(box2_t>=divh-boxh){
                dir2_t=false;
            }
            //开始设置盒子碰撞的情况
            //首先当盒子在水平方向上碰撞时,其top差的绝对值小于left差的绝对值
            if(Math.abs(box1_l-box2_l)>Math.abs(box1_t-box2_t)){
                //水平方向发生碰撞,left的差值不超过box的宽度
                //接下来就可以判断box1和box2分别在左右侧碰撞就可以了
                if(box1_l<box2_l&&box1_l+boxw>=box2_l){
                    dir1_l=false;
                    dir2_l=true;
                    console.log("红左蓝右");
                }else if(box1_l>box2_l&&box1_l<=box2_l+boxw){
                    dir1_l=true;
                    dir2_l=false;
                    console.log("红右蓝左");
                }
            }else if(Math.abs(box1_l-box2_l)<Math.abs(box1_t-box2_t)){
                //其次当盒子在竖直方向上碰撞时,其top差的绝对值大于left差的绝对值
                //竖直方向发生碰撞,top的差值不超过box的高度
                //接下来就可以判断box1和box2分别在上下侧碰撞就可以了
                if(box1_t<box2_t&&box1_t+boxh>=box2_t){
                    dir1_t=false;
                    dir2_t=true;
                    console.log("红上蓝下");
                }else if(box1_t>box2_t&&box1_t<=box2_t+boxh){
                    dir1_t=true;
                    dir2_t=false;
                    console.log("红下蓝上");
                }
            }
            //开始规定盒子的运动数值
            if(dir1_l){
                box1_l+=speed1_l;
            }else{
                box1_l-=speed1_l;
            }
            if(dir2_l){
                box2_l+=speed2_l;
            }else{
                box2_l-=speed2_l;
            }
            if(dir1_t){
                box1_t+=speed1_t;
            }else{
                box1_t-=speed1_t;
            }
            if(dir2_t){
                box2_t+=speed2_t;
            }else{
                box2_t-=speed2_t;
            }
            //写入盒子的行间样式属性,使其开始运动
            box1.style.left=box1_l+"px";
            box2.style.left=box2_l+"px";
            box1.style.top=box1_t+"px";
            box2.style.top=box2_t+"px";
            },30)
    </script>