桨顶碰撞检测乒乓

时间:2013-07-21 01:41:21

标签: javascript html5-canvas

这是乒乓球。

我可以将球和前桨的碰撞发射但不是球和球的顶部,但这个代码似乎是正确的。此代码位于球对象内。球是具有正确宽度和高度属性的正方形图像。

    // Paddle collision detection
    // Hits front of paddle
    if ((this.x) == (playerPaddle.x + playerPaddle.width) && (this.y > playerPaddle.y) && this.y < (playerPaddle.y + playerPaddle.height)) {
        console.log("front connect");
        this.vx = -this.vx;
    }
    // Hits top of paddle
    if ((this.x + this.width) >= playerPaddle.x && this.x <= (playerPaddle.x + playerPaddle.width) && (this.y + this.height) == playerPaddle.y) {
        console.log("top connect");
        this.vy = -this.vy;
    }

如果我将&& (this.y + this.height) == playerPaddle.y)更改为&& (this.y + this.height) > playerPaddle.y),则会触发,但显然这是错误的,只要球在球拍下方,它就会触发。它似乎是浏览器中的一个错误,因为它看起来对我来说是正确的。我正在使用Chrome,它似乎总是运作良好。

1 个答案:

答案 0 :(得分:2)

由于2d球是圆形的,因此您需要使用trig函数来正确确定与边缘的连接。我建议您首先通过“快速检查”检查一般区域,以防止减慢您的应用。

// Paddle Collision Detection
// Start by a global check to see if the ball is behind the paddle's face
if (this.x <= playerPaddle.x + playerPaddle.width) {
    // Get the ball's radius
    var rad = this.width/2;

    // Give yourself a 3px 'padding' area into the front of the paddle
    // For the detection fo collisions to prevent collision issues caused
    // By a ball moving > 1px in a given frame.  You may want to adjust this number
    var padding = 3;

    // Detect if ball hits front of paddle
    // y collision should be from 1/2 the ball width above the paddle's edge
    // to 1/2 the ball width below the paddle's edge
    if (this.x + padding >= playerPaddle.x + playerPaddle.width 
            && this.y - rad >= playerPaddle.y
            && this.y + rad <= playerPaddle.y + playerPaddle.height) {
        console.log("front connect");
        this.vx = -this.vx;

    // Next, do a "quick check" to see if the ball is in the correct
    // general area for an edge collision prior to doing expensive trig math
    } else if (this.y - this.height >= playerPaddle.y
            && this.y <= playerPaddle.y
            && this.x - rad >= playerPaddle.x) {

        // Get the position of the center of the ball
        var x = this.x + rad;
        var y = this.y + rad;

        // Get the position of the corner of the paddle
        var px = playerPaddle.x + playerPaddle.width;
        var py = playerPaddle.y;
        if (this.y + this.height > playerPaddle.y) {
            // if the ball is below the top edge, use the bottom corner
            // of the paddle - else use the top corner of the paddle
            py += playerPaddle.height;
        }

        // Do some trig to determine if the ball surface touched the paddle edge
        // Calc the distance (C = sqrt(A^2 + B^2))
        var dist = Math.pow(Math.pow(x - px, 2) + Math.pow(y - py, 2), 0.5);

        // Check if the distance is within the padding zone
        if (dist <= rad && dist >= rad - padding) {
            // Get the angle of contact as Arc-sin of dx/dy
            var angle = Math.asin(x - px / y - py);

            // Adjust the velocity accordingly
            this.vy = (-this.vy * Math.cos(angle)) + (-this.vx * Math.sin(angle));
            this.vx = (-this.vx * Math.cos(angle)) + (-this.vy * Math.sin(angle));
        }

    }
}