桨的碰撞检测(乒乓/破块游戏)

时间:2017-10-27 09:54:32

标签: javascript collision-detection pong

我是javascript的新手,并试图学习桨的碰撞检测。

这可能很简单,但我不知道如何创建我创建的桨的碰撞检测器。这是如何工作的以及我为了创建碰撞检测需要做些什么?

(我不需要了解砖块,我只需要创建简单的动画/游戏javascript页面。)

哦,你知道我使用的是什么样的javascript吗?因为有时它是完全不同的编码所以很难找到我可以遵循的编码类型..

三江源!

 var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 10;
var x = canvas.width/2;
var y = canvas.height-50;
var dx = 2;
var dy = -2;
var ball = drawBall 
var paddleHeight = 10;
var paddleWidth = 50;
var paddleX = (canvas.width-paddleWidth)/2;
var rightPressed = false;
var leftPressed = false;

document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);

function keyDownHandler(e) {
  if (e.keyCode == 39) {
    rightPressed = true;
  } else if (e.keyCode == 37) {
    leftPressed = true;
  }
}

function keyUpHandler(e) {
  if (e.keyCode == 39) {
    rightPressed = false;
  } else if (e.keyCode == 37) {
    leftPressed = false;
  }
}

function drawBall() {
    ctx.beginPath();
    ctx.arc(x,y, ballRadius, 0, Math.PI*2);
    ctx.fillStyle = "coral";
    ctx.fill();
    ctx.closePath();
}

function drawPaddle() {
    ctx.beginPath();
    ctx.rect(paddleX, 400, 50, 10);
    ctx.fillStyle = "lightcoral";
    ctx.fill();
    ctx.closePath();
}

function collisionDetector (){

}

function draw() {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawBall();
    drawPaddle();

    if(x + dx > canvas.width-ballRadius || x + dx < ballRadius) {
        dx = -dx;
    }
    if(y + dy > canvas.height-ballRadius || y + dy < ballRadius) {
        dy = -dy;
    }

    if(rightPressed && paddleX < canvas.width-paddleWidth) {
        paddleX += 7;
    }
    else if(leftPressed && paddleX > 0) {
        paddleX -= 7;
    }
    x += dx;
    y += dy;
}
setInterval(draw, 10);

1 个答案:

答案 0 :(得分:0)

首先,您应该评估矩形和圆形之间的距离:如果中心之间的距离大于矩形宽度的一半和球的半径之和 - 则没有碰撞。
如果您不关心像素完美评估,则将圆视为方形更容易。在这种情况下,当上述距离小于总和时 - 你有碰撞 我正在编写太空侵略者的克隆(我是一个业余爱好者,我这样做是为了好玩):https://github.com/yurybond/stackowerflow-rocks/commit/a1c1540abd453773b3ce6445d01e51ad336bbe84,我在那里写了像素完美碰撞,示例/摘录波纹管(如果两者之间存在碰撞则确定actors(在代码中的其他位置定义 - 检查Codepen链接以获取详细信息):

collision: function(actor1, actor2) {
    var X = Math.abs(actor1.x - actor2.x);
    var Y = Math.abs(actor1.y - actor2.y);
    if (Y >= INI.COLLISION_SAFE) return false;
    if (X >= INI.COLLISION_SAFE) return false;
    var w1 = parseInt(actor1.width / 2, 10);
    var w2 = parseInt(actor2.width / 2, 10);
    var h1 = parseInt(actor1.height / 2, 10);
    var h2 = parseInt(actor2.height / 2, 10);
    var T = Math.sqrt((h1 + h2) ** 2 + (w1 + w2) ** 2);
    if (
        MIN(X, Y) === 0 &&
        MAX(X, Y) >= MAX(actor1.width, actor1.height, actor2.width, actor2.height)
    )
        return false;
    var D = Math.sqrt(X ** 2 + Y ** 2);
    if (D > T) return false; // not close enough
    var minWH = MIN(w1, w2, h1, h2);
    if (D <= minWH) return true; //ultra close
    ///////// pixel perfect evaluation ////////////
    var act1 = new Vector(actor1.x, actor1.y);
    var act2 = new Vector(actor2.x, actor2.y);
    var direction = act1.direction(act2);
    var point1 = new Vector(
        actor1.x + direction.x * w1,
        actor1.y + direction.y * h1
    );
    var point2 = new Vector(
        actor2.x - direction.x * w2,
        actor2.y - direction.y * h2
    );
    var x = MIN(point1.x, point2.x);
    var y = MIN(point1.y, point2.y);
    var w = MAX(point1.x, point2.x) - MIN(point1.x, point2.x);
    var h = MAX(point1.y, point2.y) - MIN(point1.y, point2.y);
    if (w === 0 && h === 0) return false;
    if (w === 0) {
        w = MIN(w1, w2);
        x = x - w;
        w = w * 2;
    }
    if (h === 0) {
        h = MIN(h1, h2);
        y = y - h;
        h = h * 2;
    }
    var area = new Square(x, y, w, h);
    var area1 = new Square(
        (area.x - actor1.x) * direction.x + w1 * direction.x,
        (area.y - actor1.y) * direction.y + h1 * direction.y,
        area.w,
        area.h
    );
    var area2 = new Square(
        (area.x - actor2.x) * direction.x * -1 + w2 * direction.x * -1,
        (area.y - actor2.y) * direction.y * -1 + h2 * direction.y * -1,
        area.w,
        area.h
    );
    var CTX1 = LAYER.temp;
    var CTX2 = LAYER.temp2;
    ENGINE.draw("temp", 0, 0, SPRITE[actor1.name]);
    ENGINE.draw("temp2", 0, 0, SPRITE[actor2.name]);
    var data1 = CTX1.getImageData(area1.x, area1.y, area1.w, area1.h);
    var data2 = CTX2.getImageData(area2.x, area2.y, area2.w, area2.h);
    var DL = data1.data.length;
    var index;
    for (index = 3; index < DL; index += 4) {
        if (data1.data[index] > 0 && data2.data[index] > 0) return true;
    }
    return false;
},

如果这个例子,在我检查矩形是否重叠(如上所述)后,我计算精灵的哪些部分实际重叠,然后检查每个精灵是否在同一个点(在重叠的矩形中)有非透明像素)。
我还建议使用requestAnimationFrame()而不是setInterval() 我希望这可以帮助你开始。