Обнаружение столкновения между шаром и дугой, а также между дугой и дугой - PullRequest
0 голосов
/ 17 января 2019

Я делаю игру в стиле понг на JavaScript, где весло изогнуто. У меня уже есть столкновение между 2 шарами, но у меня, похоже, проблемы с мячом и дугой.

Я уже смотрел эту тему:

Обнаружение столкновения шара с дугой

Но я не могу заставить этот ответ работать для меня. Возможно, потому что я рисую дугу по-другому. Вот мои переменные, а также как рисование весла на холсте. Когда игрок нажимает клавишу, углы для весла увеличиваются, так что он вращается вокруг игрока.

Если кто-нибудь может помочь, я был бы признателен.

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;
        }
    };
}

Редактировать: Извините, я забыл добавить свою попытку кода столкновения. Я запускаю его каждый кадр, но кажется, что он не определяет, когда они сталкиваются.

Массив объектов представляет собой каждый шарик на экране и двух игроков, а массив игроков содержит только двух игроков.

//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");
    }
}
...