简体   繁体   English

Javascript-圆圆碰撞问题

[英]Javascript - Circle-Circle Collision Issue

I am making a game in HTML5, Canvas, and this is my code for resolving collision between two moving circles: 我正在用HTML5 Canvas制作游戏,这是我的代码,用于解决两个运动的圆之间的碰撞:

function resCCCol(a, b) {
    var dx = a.x - b.x;
    var dy = a.y - b.y;

    var dist = dx * dx + dy * dy;

    var vx = b.vx - a.vx;
    var vy = b.vy - a.vy;

    var dot = dx * vx + dy * vy;

    if (dot > 0) {
        var scale = dot / dist;

        var cx = dx * scale;
        var cy = dy * scale;

        var mass = a.r + b.r;

        var cw1 = 2 * b.r / mass;
        var cw2 = 2 * a.r / mass;

        a.vx += cw1 * cx
        a.vy += cw1 * cy
        b.vx -= cw2 * cx
        b.vy -= cw2 * cy
    }
}

If I set the coordinates so that the circles overlap but still have their velocity both at 0, the circles won't push out each other, that is the problem. 如果我设置坐标以使圆重叠,但它们的速度都仍为0,则圆不会互相推出,这就是问题所在。 How do I fix this? 我该如何解决?

EDIT: Fiddle: http://jsfiddle.net/yP7xf/2/ , click "Glitch it!" 编辑:小提琴: http : //jsfiddle.net/yP7xf/2/ ,单击“小故障!” to see the glitch, as you see they won't separate. 看到小故障,就像您看到的那样,它们不会分开。

I'm not sure what the purpose of dot is (maybe I'm missing some maths knowledge here), but two circles colliding happens if dist < sum(radii) . 我不确定dot的用途是什么(也许我在这里缺少一些数学知识),但是如果dist < sum(radii)则会发生两个圆的碰撞。 Should this occur, you should deflect the circles, but ensure they have at least some small speed to ensure they separate. 如果发生这种情况,您应该使圆偏斜,但是要确保圆至少有一些小的速度以确保圆分开。

When two circles overlap with no velocity your resCCCol() method won't work since dot is 0 . 当两个圆没有速度重叠时,您的resCCCol()方法将无效,因为dot0 Even if you change the if statement to execute on dot >= 0 , you're still left with 0 velocity. 即使将if语句更改为在dot >= 0上执行,您仍然保持0速度。

if (dot > 0) { //dot === 0
    var scale = dot / dist; //scale === 0

    var cx = dx * scale; //cx === 0
    var cy = dy * scale; //cy === 0

    var mass = a.r + b.r;

    var cw1 = 2 * b.r / mass;
    var cw2 = 2 * a.r / mass;

    a.vx += cw1 * cx // 0
    a.vy += cw1 * cy // 0
    b.vx -= cw2 * cx // 0
    b.vy -= cw2 * cy // 0
}

You should handle cases when dot === 0 . 您应该处理dot === 0 The easiest way is to simply give them a set velocity when the velocity is 0 : 最简单的方法是在速度为0时简单地给它们设置速度:

if (dot > 0) { 
    ... 
} else {
    a.vx = 1;
    a.vy = 1;
    b.vx = -1;
    b.vy = -1;
}

This, of course, will only propel them away from each other towards opposite corners of the screen, but you could easily implement something that better adheres to the laws of physics (ignoring the fact that two objects can't take up the same space). 当然,这只会将它们彼此推向屏幕的相对角,但是您可以轻松实现更好地遵守物理定律的东西(忽略两个物体不能占据同一空间的事实) 。

It's not entirely clear what the best way to handle this would be, and I think it would be better to make sure you don't end up in this situation in the first place (by making sure they don't ever overlap with zero velocity), but a quick and dirty fix is to check dot === 0 and if so, give them some velocity. 目前尚不清楚解决此问题的最佳方法是什么,我认为最好首先确保您不会遇到这种情况(通过确保它们永远不会以零速度重叠) ),但一种快速而肮脏的解决方法是检查dot === 0 ,如果是,请给它们一些速度。 For example: 例如:

if (dot === 0) {
    // numbers pulled completely out of thin air...
    a.vx = 0.5;
    a.vy = 0.5;
    b.vx = -0.5;
    b.vy = -0.5;
}

http://jsfiddle.net/yP7xf/5/ http://jsfiddle.net/yP7xf/5/

Now what velocity should you give them? 现在,您应该给它们多大的速度? That's something you'll need to work out. 那是您需要解决的问题。 Probably you want them to move apart so you can probably calculate some vector based on a line from the center of one to the center of the other and send one in one direction along that vector and the other in the other at whatever speed you think is appropriate. 可能是您希望它们分开,以便您可以根据从一个中心到另一个中心的一条线计算一些矢量,然后以您认为的任何速度沿一个矢量向一个方向发送,向另一个发送另一个方向适当。 But if they are laid exactly on top of each other (centers at the same point), then you'll need to account for that case too. 但是,如果它们正好位于彼此的顶部(中心在同一点),那么您也需要考虑这种情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM