如何正确执行两个球体之间的碰撞检测?

时间:2019-05-30 20:28:46

标签: javascript collision-detection game-physics

Hello world :)正在制作一个小型动画,其中一堆球体在画布上跳跃,彼此,地板,墙壁和天花板弹起。

现在,这完美无误地工作了,直到我添加的球超出了一个级别中该区域所能容纳的范围。在这一点上,球体沉入一个平面的球体中,彼此相互接合并推动其他球体穿过壁边界,这通常是不会发生的。

但是,应该说我不完全了解我用来实现结果的功能,因此可能与它有关。将在下面发布我的碰撞检测功能,希望你们中的一个可以帮助我更进一步:)

借用的功能:

/**
 * Rotates coordinate system for velocities
 *
 * Takes velocities and alters them as if the coordinate system they're on was rotated
 *
 * @param  Object | velocity | The velocity of an individual particle
 * @param  Float  | angle    | The angle of collision between two objects in radians
 * @return Object | The altered x and y velocities after the coordinate system has been rotated
 */

function rotate(velocity, angle) {
    const rotatedVelocities = {
        x: velocity.x * Math.cos(angle) - velocity.y * Math.sin(angle),
        y: velocity.x * Math.sin(angle) + velocity.y * Math.cos(angle)
    };

    return rotatedVelocities;
}

/**
 * Swaps out two colliding particles' x and y velocities after running through
 * an elastic collision reaction equation
 *
 * @param  Object | particle      | A particle object with x and y coordinates, plus velocity
 * @param  Object | otherParticle | A particle object with x and y coordinates, plus velocity
 * @return Null | Does not return a value
 */

function resolveCollision(particle, otherParticle) {
    const xVelocityDiff = particle.velocity.x - otherParticle.velocity.x;
    const yVelocityDiff = particle.velocity.y - otherParticle.velocity.y;
    console.log("Resolving");

    const xDist = otherParticle.x - particle.x;
    const yDist = otherParticle.y - particle.y;
    // alert(xVelocityDiff * xDist + yVelocityDiff * yDist)

    // Prevent accidental overlap of particles
    if (xVelocityDiff * xDist + yVelocityDiff * yDist >= 0) {
        console.log("Resolving IF");

        // Grab angle between the two colliding particles
        const angle = -Math.atan2(otherParticle.y - particle.y, otherParticle.x - particle.x);

        // Store mass in var for better readability in collision equation
        const m1 = particle.mass;
        const m2 = otherParticle.mass;

        // Velocity before equation
        const u1 = rotate(particle.velocity, angle);
        const u2 = rotate(otherParticle.velocity, angle);

        // Velocity after 1d collision equation
        const v1 = { x: u1.x * (m1 - m2) / (m1 + m2) + u2.x * 2 * m2 / (m1 + m2), y: u1.y };
        const v2 = { x: u2.x * (m1 - m2) / (m1 + m2) + u1.x * 2 * m2 / (m1 + m2), y: u2.y };

        // Final velocity after rotating axis back to original location
        const vFinal1 = rotate(v1, -angle);
        const vFinal2 = rotate(v2, -angle);

        // Swap particle velocities for realistic bounce effect
        particle.velocity.x = vFinal1.x;
        particle.velocity.y = vFinal1.y;

        otherParticle.velocity.x = vFinal2.x;
        otherParticle.velocity.y = vFinal2.y;
    }
}

球属性:


// Objects
function Ball(x, y, dy, dx, radius, color) {
    this.x = x
    this.y = y
    // this.dy = dy;
    // this.dx = dx;
    this.velocity = {
        x:dx,
        y:dy
    }
    this.radius = radius
    this.color = color
    this.mass = 1;

    this.collision = ()=> {
        for (var index = 0; index < objects.length; index++) {
            var coin = objects[index];
            if (this === coin) {
                continue;
            }
            if (getDistance(this.x, this.y, coin.x, coin.y) - (this.radius + coin.radius) < 0) {
                // alert('hi');
                console.log("collision:");

                resolveCollision(this, coin)
            }
        }
    }
}




Ball.prototype.update = function() {
    if (this.y + this.radius + this.velocity.y > canvas.height) {
        this.velocity.y = (-this.velocity.y * parseFloat(0.85));

    }else {
        this.velocity.y += gravity;
    }
    this.y += this.velocity.y;
    this.x += this.velocity.x;

    if (this.x + this.radius + this.velocity.x > canvas.width) {
        this.velocity.x = -this.velocity.x;

    }
    if (Math.sign(this.velocity.x) === 1) {
        this.velocity.x -= 0.01;
    } else if (Math.sign(this.velocity.x) === -1) {
        this.velocity.x += 0.01;


    }
    if (this.x - this.radius - this.velocity.x < 0) {
        this.velocity.x = Math.abs(this.velocity.x);
       }






    this.draw()
}

真的很感谢这里的任何帮助,我正在努力提高我在该领域的技能,并感到非常需要再次阅读我的几何书籍:D

0 个答案:

没有答案