简体   繁体   English

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

[英]Change Ball Direction after collision with another ball

I need to change Ball Direction after collision with another ball or with a edge of the window. 与另一个球或窗口的边缘碰撞后,我需要更改“球的方向”。 I managed to do something like that: 我设法做这样的事情:

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

And same for another edges. 同样的另一个优势。

I'm trying to use same method for changing direction of balls after they collide with each other, but it's just not working / it's weird. 我试图使用相同的方法在球彼此碰撞后改变球的方向,但这只是不起作用/很奇怪。 Can anyone help me? 谁能帮我?

When balls collide, make vector connecting ball centers ( N ) and normalize it ( uN ) 球碰撞时,使连接球心的向量( N )并对其进行归一化( uN

Components of velocities parallel to N (normal) are exchanged (due to impulse law) 交换与N (法向)平行的速度分量(由于脉冲定律)

Components of velocities perpendicular to N (tangential) remain the same 垂直于N (切向)的速度分量保持不变

To get components in given local system, use scalar and cross product: 要在给定的本地系统中获取组件,请使用标量和叉积:

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

 V1n = cross(V1, uN)
 V2n = cross(V2, uN)

after collision 碰撞后

V1t' = V2t
V2t' = V1t

V1n' = V1n
V2n' = V2n

To return into global system (I did not checked signs thoroughly): 返回全球系统(我没有彻底检查迹象):

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

(This is essentially dot and cross products again, but I expanded expressions to show different bases) (这实际上又是点和叉积,但是我扩展了表达式以显示不同的底数)

Note that this approach is like to ball-edge collision, when N is normal to the border and you reverse only one component of velocity vector. 请注意,这种方法类似于球形碰撞,当N垂直于边界并且您只反转速度矢量的一个分量时。

For your BouncingBall class, you can have a method like flipDirection() , but you can have a finer directional control by splitting it into 2 methods which filps the direction of the ball vertically and horizontally. 对于您的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);
    }
}

Depending on how you want the ball to bounce off. 取决于您希望球反弹的方式。 In a simple bounce off, the balls can bounce towards 4 possible directions: 通过简单的弹跳,球可以向4个可能的方向弹跳:

  • North West 西北
  • North East 东北
  • South West 西南
  • South East 东南

The direction of the ball to bounce off will be relative to the position of the ball it is colliding with and you do not want 2 collided balls which move in the same direction to switch direction just because they collided. 弹起的球的方向将与要碰撞的球的位置有关,并且您不希望两个碰撞的球沿相同的方向移动以仅因为它们碰撞而切换方向。 Hence you need to check the positions of the 2 balls, and flipDirection() becomes insufficinet to achieve that. 因此,您需要检查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();
    }
}

For example, to change direction when hitting the walls on the left and right: 例如,要在撞到左右墙壁时改变方向:

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

Same logic for verticalReverse. VerticalReverse的逻辑相同。

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

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