我正在尝试制作一个弹跳球的程序。我试过一些条件,但我没有得到我想要的。球继续在框架的对角线方向上来回移动。问题出在哪里?我强调了这个程序的主要逻辑
这是程序:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class MovingBall2D extends JPanel{
int x_Pos=0;
int y_Pos=0;
int speedX=1;
int speedY=1;
int diameter=30;
int height=30;
int frameX=500;
int frameY=500;
MovingBall2D() {
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if( x_Pos > ( frameX - diameter ) ) { // <------ logic starts from here
x_Pos = frameX - diameter;
speedX = -1;
}
else if(x_Pos < 0) {
x_Pos = 0;
speedX = 1;
}
else if( y_Pos > ( frameY - diameter ) ) {
y_Pos = frameY - height;
speedY = -1;
}
else if(y_Pos < 0) {
y_Pos = 0;
speedY = 1;
}
x_Pos = x_Pos + speedX;
y_Pos = y_Pos + speedY;
repaint();
}
};
new Timer(10,taskPerformer).start(); // <------- logic ends here
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(x_Pos,y_Pos,diameter,height);
}
}
class Main2D {
Main2D() {
JFrame fr=new JFrame();
MovingBall2D o = new MovingBall2D();
fr.add(o);
fr.setSize(500,500);
fr.setVisible(true);
fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
new Main2D();
}
}
编辑-球来回移动为什么会发生这种情况我期待这里显示的输出。如果任何人都不清楚这个问题,请编译并运行以查看输出
球从0,0的位置开始。从那时起,在每一个时间步长,直到它撞到墙上,它的x位置和y位置都会增加1。所以在时间471,它的位置是(471471)。在这一点上,转身的x和y条件都成立,所以两者都切换,球完全转身。
如果您将起始位置更改为类似(0,30)的值,或者将其中一个速度更改为1或-1以外的值,您将看到您的代码可以工作。球总是沿着某个循环,但由于框架大小和球的位置,你的球恰好很小。
但是,我建议您删除其他条件。在一帧中,球可能向左和向下偏得太远,因此在该帧中,两种情况都应该固定,而不仅仅是一种。此外,您可能会注意到球在y方向上继续离开屏幕。这是因为主框架设置为与面板相同的高度。框架高度包括用于顶部窗条的部分,因此它需要比它所支撑的面板稍大。
在所有四种情况下,您都将相应的速度设置为-1:
speedX = -1;
//...
speedY = -1;
但只有当X大于宽度或Y大于高度时,才希望它为负。在另外两种情况下,您希望速度为正。
或者,也许你想要的是
speedX *= -1;
这会将速度切换到相反的方向。
在我看来,speedX
和speedY
没有正确更新。我认为应该是这样的:
if( x_Pos > ( frameX - diameter ) ) { // <------ logic starts from here
x_Pos = frameX - diameter;
speedX = -1;
}
else if(x_Pos < 0) {
x_Pos = 0;
speedX = 1;
}
else if( y_Pos > ( frameY - diameter ) ) {
y_Pos = frameY - height;
speedY = -1;
}
else if(y_Pos < 0) {
y_Pos = 0;
speedY = 1;
}
x_Pos = x_Pos + speedX;
y_Pos = y_Pos + speedY;
我认为您拥有所有正确的逻辑,但您的初始化确保它沿对角线(从左下到右上)反弹
更改它们,使用随机值或像一样对它们进行硬编码
int x_Pos=100; // These are changed so the ball no longer starts at bottom left
int y_Pos=20;
int speedX=1; //This should be fine as long as your initial position is different
int speedY=1;
int diameter=30;
int height=30;
int frameX=500;
int frameY=500;
我也认为这将工作
int x_Pos = 100* Math.Rand(1);
等等。