球与弧之间以及弧与弧之间的碰撞检测

时间:2019-01-16 22:14:20

标签: javascript math 2d collision-detection game-physics

我正在用JavaScript制作乒乓球风格的游戏,桨板是弯曲的。我已经在两个球之间发生碰撞,但似乎在球和弧线方面遇到了麻烦。

我已经看过这个线程了:

Collision detection of a ball with an arc

但是我似乎无法使那里的答案对我有用。也许是因为我画的弧线不同。 这是我的变量,以及如何将球拍绘制到画布上。当玩家按下按键时,桨的角度会增加,因此它会围绕玩家旋转。

如果有人可以提供帮助,我将不胜感激。

https://i.stack.imgur.com/kz0ZV.png

function Player(name, radius, innerColour, outerColour, x, y)
{
    this.prop = {
                    name:        name,
                    innerColour: innerColour,
                    outerColour: outerColour
                };

    this.phys = {
                    x:      x,
                    y:      y,
                    dx:     0,
                    dy:     0,
                    mass:   radius ** 3,
                    radius: radius

                };

    this.padd = {                                                                               
                    innerRadius: 65,                                                                              
                    outerRadius: 85,                                                                                
                    active:      true,                                                                               
                    startAngle:  225,                                                                              
                    centerAngle: 270,                                                                                
                    endAngle:    315,                                                                             
                    rotation:    false
                };

    this.draw = function()
    {
        var inR   = this.padd.innerRadius;
        var outR  = this.padd.outerRadius;

        var inC  = Math.sqrt((inR ** 2)  * 2);
        var outC = Math.sqrt((outR ** 2) * 2);

        var sAng = this.padd.startAngle;
        var cAng = this.padd.centerAngle;
        var eAng = this.padd.endAngle;

        //Draw paddle
        ctx.beginPath();
        ctx.moveTo(this.rotatePoint(inR,  sAng, "x"), this.rotatePoint(inR,  sAng, "y"));
        ctx.arcTo (this.rotatePoint(inC,  cAng, "x"), this.rotatePoint(inC,  cAng, "y"),                                                 
                   this.rotatePoint(inR,  eAng, "x"), this.rotatePoint(inR,  eAng, "y"), inR);
        ctx.lineTo(this.rotatePoint(outR, eAng, "x"), this.rotatePoint(outR, eAng, "y"))
        ctx.arcTo (this.rotatePoint(outC, cAng, "x"), this.rotatePoint(outC, cAng, "y"),                                                   
                   this.rotatePoint(outR, sAng, "x"), this.rotatePoint(outR, sAng, "y"), outR);
        ctx.lineTo(this.rotatePoint(inR,  sAng, "x"), this.rotatePoint(inR,  sAng, "y"));
        ctx.fillStyle = this.prop.outerColour;
        ctx.fill();
        ctx.closePath();
    };
    this.rotatePoint = function(radius, angle, axis)
    {
        var x = this.phys.x;
        var y = this.phys.y;

        var radians = angle * (Math.PI / 180.0);
        var x1      = x + radius;

        var newX = Math.cos(radians) * (x1 - x) + x;
        var newY = Math.sin(radians) * (x1 - x) + y;

        if (axis == "x")
        {
            return newX;
        }
        else if (axis == "y")
        {
            return newY;
        }
    };
}

编辑:对不起,我忘记添加尝试输入碰撞代码了。 我每帧都运行它,但似乎无法检测到它们何时发生碰撞。

objects数组既是屏幕上的每个球又是2个玩家,并且players数组仅包含2个玩家。

//Calculates events, speed and trajectory for paddle collisions
function paddleCollision()
{
    for (var obj in objects)
    {
        for (var player in players)
        {
            var sAng = players[player].padd.startAngle * (Math.PI / 180.0);
            var eAng = players[player].padd.endAngle   * (Math.PI / 180.0);

            var inR  = players[player].padd.innerRadius;
            var outR = players[player].padd.outerRadius;

            var ballR = objects[obj].phys.radius;

            var collides = false;

            var dX = objects[obj].phys.x - players[player].phys.x;
            var dY = objects[obj].phys.y - players[player].phys.y;

            var dist = Math.sqrt((dX ** 2) + (dY ** 2));
            var dir  = Math.atan2(dY, dX);

            var tanAng = Math.asin(ballR / dist);
            var dir0   = dir + tanAng;
            var dir1   = dir - tanAng;

            if (dist + ballR > inR && dist - ballR < outR)
            {
                var d  = dir  > sAng && dir  < eAng;
                var d0 = dir0 > sAng && dir0 < eAng;
                var d1 = dir1 > sAng && dir1 < eAng;

                if (d || d0 && d1)
                {
                    collides = true;
                }
                else if (d0 != d1)
                {
                    var x0 = players[player].phys.x + outR * Math.cos(sAng) - objects[obj].phys.x;
                    var y0 = players[player].phys.y + outR * Math.sin(sAng) - objects[obj].phys.y;

                    var x1 = players[player].phys.x + outR * Math.cos(eAng) - objects[obj].phys.x;
                    var y1 = players[player].phys.y + outR * Math.sin(eAng) - objects[obj].phys.y;

                    if ((x0 ** 2) + (y0 ** 2) < (ballR ** 2) || (x1 ** 2) + (y1 ** 2) < (ballR ** 2))
                    {
                        collides = true;
                    }
                }
            }
        }
    }

    if (collides)
    {
        console.log("HITTING");
    }
}

1 个答案:

答案 0 :(得分:0)

这对我有用:

    function arcsCollision(first, second) {
    const dx = first.x - second.x;
    const dy = first.y - second.y;
    const distance = Math.sqrt(dx**2 + dy**2);
    return (
        distance
        <=
        (first.radius + second.radius + 0.1)
    );
}

function arcAndRectCollision(arc, rect) {

    return (
        arc.x - arc.radius < rect.x ||
        arc.x + arc.radius > rect.width ||
        arc.y - arc.radius < rect.y ||
        arc.y + arc.radius > rect.height
    );
}

你可以去这个网站了解更多信息。 https://spicyyoghurt.com/tutorials/html5-javascript-game-development/collision-detection-physics