我得到的部分是当球与方块碰撞时,它会删除方块,但是我也想知道球是否击中方块的顶部,底部,左侧或右侧并相应地反弹。我已经尝试过了,但是效果不佳。它只是跳来跳去。我已从下面的代码中删除了该部分,因为它不起作用。谁能帮我解决这个问题?也许举个例子或告诉我它如何工作?

<canvas id="can" height="500" width="1000"></canvas>


        var c = document.getElementById("can");
        var ctx = c.getContext("2d");
        var blocks= [];
        var paddle = {x:450,y:480,h:10,w:100};
        var ball = {r:7,x:500,y:469};
        var rows=[0,1,2,3,4];
        var px = paddle.x, py = paddle.y;
        var pxv=0;
        var by = ball.y, bx = ball.x;
        var bxv = -1.5, byv = -1.5;


        function Block(h,w,x,y,c) {
            this.h = h;
            this.w = w;
            this.x = x;
            this.y = y;
            this.c = c;
        }
        for(var i =0, len=rows.length;i<len;i++){
            for(var j=0; j<20;j++) {
            blocks.push(new Block(20,50,j*50,i*20,rows[i]))
        }
        }
        document.addEventListener("keydown",keyPush);
        document.addEventListener("keyup",keyRelease);
        function keyRelease(evt) {
            switch(evt.keyCode) {
                case 37:
                    pxv=0;
                    break;
                case 39:
                    pxv=0;
                    break;
            }
        }
        function keyPush(evt) {
            switch(evt.keyCode) {
                case 37:
                    pxv=-5;
                    break;
                case 39:
                    pxv=5
                    break;
            }
        }
        function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
            return ax < bx+bw && bx < ax+aw && ay < by+bh && by < ay+ah;
        };
        function draw(){
        ctx.clearRect(0,0,1000,500)
        bx+=bxv;
        by+=byv;
        px+=pxv;

        if(px > 900) {
            px = 900;
        }
        else if(px < 0) {
            px = 0;
        }
        for(var i = 0, len=blocks.length;i<len;i++) {
            var bl = blocks[i];
            if(AABBIntersect(bx,by,ball.r,ball.r,bl.x,bl.y,bl.w,bl.h)) {
                blocks.splice(i,1);
                i--;
                len--;
            }
        }
        if(bx < 0) {
            bxv = bxv*-1;
        }
        if(bx > 1000) {
            bxv = bxv*-1;
        }
        ctx.fillStyle = "#ff4b38"
        ctx.fillRect(px,py,paddle.w,paddle.h);
        for(var i = 0, len=blocks.length; i<len; i++){

                if(blocks[i].c === 0) {
                    ctx.fillStyle = "#ff4b38"
                }
                else if(blocks[i].c === 1) {
                    ctx.fillStyle = "#ffba19"
                }
                else if(blocks[i].c === 2) {
                    ctx.fillStyle = "#fcee25"
                }
                else if(blocks[i].c === 3) {
                    ctx.fillStyle = "#26db02"
                }
                else if(blocks[i].c === 4) {
                    ctx.fillStyle = "#2d69ff"
                }
                  ctx.fillRect(blocks[i].x,blocks[i].y,blocks[i].w,blocks[i].h);
                  ctx.beginPath();
                  ctx.arc(bx,by,ball.r,0,2*Math.PI,false);
                  ctx.fillStyle = "gray";
                  ctx.fill();

        }
        }
        setInterval(draw,10);

最佳答案

我敢肯定还有更多的方法可以做到这一点,但这就是我会做到的。

在碰撞检测功能内部,您应该具有if语句以从x或y方向检测是否。您需要对其进行调整,以免不确定它是否稍后会出错,但首当其冲的是这样的:

function AABBIntersect(ax, ay, aw, ah, bx, by, bw, bh) {
    var bool = ax < bx + bw && bx < ax + aw && ay < by + bh && by < ay + ah;
    if(bool){
        if(ax == bx || ax == bx + bw){
            bxv *= -1;
            cl("x");
        }else{
            byv *= -1;
            cl("y");
        }
    }

    return bool;
};


下一个问题是您没有桨碰撞检测功能,因此它会反弹回来,但会穿过桨。因此,您可以在draw()函数中执行以下操作。我把它放在你的if(bx > 1000)之后:

if(bx >= px && bx <= px + paddle.w && by >= py && by <= py + paddle.h){
    byv *= -1;
}


我还将您的setInterval放在var上,以便在所有块都消失或球低于桨叶时将其清除。否则,它将无限延伸到任何地方。

09-19 08:10