与另一个球碰撞后改变球的方向

时间:2018-03-02 06:16:43

标签: java algorithm logic

我需要在与另一个球或窗户边缘碰撞后改变球方向。 我设法做了类似的事情:

y += yMove;
x += xMove;

//if the ball moves to the right edge of the window, turn around. 
if(x > width - size)
{   
    x = width - size;
    xMove *= -1;
    if (xMove > 0) {
       xSpeed = xMove + (Math.random() * (1));
    }
    if (xMove <= 0) {
       xSpeed = xMove - (Math.random() * (1));
    }
    if (yMove > 0) {
       ySpeed = yMove + (Math.random() * (1));
    }
    if (yMove <= 0) {
       ySpeed = yMove - (Math.random() * (1));
    }
}

另一条边也一样。

我尝试使用相同的方法在球相互碰撞后改变球的方向,但它不起作用/它很奇怪。任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:3)

当球碰撞时,制作矢量连接球中心( N )并将其标准化( uN

交换平行于 N (正常)的速度分量(由于脉冲定律)

垂直于 N (切向)的速度分量保持不变

要在给定的本地系统中获取组件,请使用标量和交叉产品:

 V1t = dot(V1, uN)  
 V2t = dot(V2, uN)  

 V1n = cross(V1, uN)
 V2n = cross(V2, uN)
碰撞后

V1t' = V2t
V2t' = V1t

V1n' = V1n
V2n' = V2n

返回全球系统(我没有仔细检查过标志):

V1x = V1t` * uN.X + V2n` * uN.Y 
V1y = -V1t` * uN.Y + V2n` * uN.X 

(这实际上是点和交叉产品,但我扩展表达式以显示不同的基础)

请注意,这种方法类似于球边碰撞,当N与边界垂直时,您只反转速度矢量的一个分量。

答案 1 :(得分:1)

对于你的BouncingBall类,你可以使用像flipDirection()这样的方法,但你可以通过将它分成2个方法来进行更精细的方向控制,这些方法可以垂直和水平地填充球的方向。

class BouncingBall{
    public void horizontalFlip(){
        moveX *= -1;
    }

    public void verticalFlip(){
        moveY *= -1;
    }

    //To have move control over each direction, you can have a method for each direction.
    public void moveNorth(){
        moveY = Math.abs(moveY) * -1;
    }

    public void moveSouth(){
        moveY = Math.abs(moveY);
    }

    public void moveWest(){
        moveX = Math.abs(moveX) * -1;
    }

    public void mpveEast(){
        moveX = Math.abs(moveX);
    }
}

取决于你想要球反弹的方式。在一次简单的反弹中,球可以向4个可能的方向反弹:

  • 西北
  • North East
  • 西南
  • 东南

球反弹的方向将相对于它碰撞的球的位置而你不希望2个碰撞的球在相同的方向上移动以仅仅因为它们相撞而切换方向。因此你需要检查2个球的位置,而flipDirection()变得不足以实现这一点。

if(b1.intersects(b2)){
    if(b1.getX() < b2.getX()){ // b1 above b2
        b1.moveNorth();
        b2.moveSouth();
    }
    else{
        b1.moveSouth();
        b2.moveNorth();
    }
   if(b1.getY() < b2.getY()){ // b1 at left side of b2
        b1.moveWest();
        b2.moveEast();
    }
    else{
        b1.moveEast();
        b2.moveWest();
    }
}

例如,要在左右两侧撞墙时改变方向:

if(ball.getPosX() <= 0 || ball.getPosX() >= PNL_WIDTH-Ball.SIZE)
    ball.horizontalReverse();

verticalReverse的逻辑相同。