【发布时间】:2021-08-12 08:10:11
【问题描述】:
我正在创建一个弹跳球项目,每次单击鼠标时都会以随机速度、随机大小和随机位置生成球,除了一件事之外,一切都运行良好,当球击中时让我们说从顶部和左侧的墙壁完全反弹回来但是当球击中窗口的底部和右侧部分时它们也会被反弹但并不完美,我的意思是球甚至在之前从窗口的右侧反弹回来当几乎一半的球超出窗口时,从底部击中墙壁。 有什么问题,为什么会这样?
这是代码:
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
//To generate random colors
/*new Color((int) Math.floor((Math.random() * 256)),(int) Math.floor((Math.random() * 256)),(int)
Math.floor((Math.random() * 256)))*/
public class bouncingBalls {
public static void main(String[] args) {
Program program = new Program();
program.run();
}
}
class Program {
protected JFrame mainFrame;
protected DrawPanel drawPanel;
protected java.util.List<Ball> balls;
void run() {
balls = new ArrayList<>();
mainFrame = new JFrame();
drawPanel = new DrawPanel();
mainFrame.getContentPane().add(drawPanel);
mainFrame.setTitle("Bouncing Balls");
mainFrame.setSize(640, 480);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
/* Generate balls */
mainFrame.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
System.out.println("Mouse clicked");
Ball ball = new Ball(
/* Random positions from 0 to windowWidth or windowHeight */
(int) Math.floor(Math.random() * 640),
(int) Math.floor(Math.random() * 480),
/* Random size from 10 to 30 */
(int) Math.floor(Math.random() * 20) + 10,
/* Random RGB colors*/
new Color(0x851E3E),
/* Random velocities from -5 to 5 */
(int) Math.floor((Math.random() * 10) - 5),
(int) Math.floor((Math.random() * 10) - 5)
);
balls.add(ball);
}
});
while (true) {
for (Ball b: balls) {
b.update();
}
/* Give Swing 10 milliseconds to see the update! */
try {
Thread.sleep(30);
} catch (InterruptedException e) {
e.printStackTrace();
}
mainFrame.repaint();
}
}
class DrawPanel extends JPanel {
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
for (Ball b: balls) {
b.draw(graphics);
}
}
}
class Ball {
private int posX, posY, size;
private Color color;
private int vx;
private int vy;
public Ball(int posX, int posY, int size, Color color, int vx, int vy) {
this.posX = posX;
this.posY = posY;
this.size = size;
this.color = color;
this.vx = vx;
this.vy = vy;
}
void update() {
if (posX > mainFrame.getWidth()-size*2 || posX < 0) {
vx *= -1;
}
if (posY > mainFrame.getHeight()-size-32 || posY < 0) {
vy *= -1;
}
if (posX > mainFrame.getWidth()-size*2) {
posX = mainFrame.getWidth()-size*2;
}
if (posX < 0) {
posX = 0;
}
if (posY > mainFrame.getHeight()-size-32) {
posY = mainFrame.getHeight()-size-32;
}
if (posY < 0) {
posY = 0;
}
this.posX += vx;
this.posY += vy;
}
void draw(Graphics g) {
g.setColor(color);
g.fillOval(posX, posY, size, size);
g.getClipBounds();
g.getClipBounds();
}
}
}
【问题讨论】:
-
听起来您没有正确考虑球的厚度。为什么你的更新方法中有
size-32和size*2?32是什么?另外,为什么大小乘以2?这会让球离边缘太远,听起来就像你正在经历的行为。 -
为什么是
-size-32?不应该是posY + size > height吗?另外,请注意,Swing 不是线程安全的。使用Thread的方式可能会导致线程之间的脏读/写。 SwingTimer可能是更好的解决方案 -
请参阅:stackoverflow.com/questions/54028090/…,了解使用摇摆计时器的球动画示例。