我需要在与另一个球或窗户边缘碰撞后改变球方向。 我设法做了类似的事情:
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));
}
}
另一条边也一样。
我尝试使用相同的方法在球相互碰撞后改变球的方向,但它不起作用/它很奇怪。任何人都可以帮助我吗?
答案 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个可能的方向反弹:
球反弹的方向将相对于它碰撞的球的位置而你不希望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的逻辑相同。