如何在Java中绘制以不同速度移动的多个对象?

我正在为课堂上的家庭作业工作,而且它已经很晚了,因为尽管我正在做的所有研究,我似乎无法理解这些材料。 我是初学者,对java的方式不太了解。 另外,这是我的第一篇文章,所以当你读这篇文章时请原谅。

我正在建立我的教科书的源代码,我最近为过去的作业更新了,但现在我正在尝试生成一个绘制多个正方形的类,并以不同的速度独立移动这些对象。 他们都需要从墙上反弹。 我按照说明创建了两个数组,它们将随机的x和y值保持在1到10之间。但是,我对数组很困难,我确信我没有正确地执行它。 所以,我希望得到一些反馈,看看我是否正确设置了它。

我有一个jpanel拉起和绘图,只要有一个正方形,它工作得很好,从墙壁反弹,但当我画一个以上时,事情会改变。 不要独立移动,它们也有相同的速度。 有些甚至不时消失。 这真的让我失望了。 我感谢任何帮助!

简而言之,我正在尝试绘制所有沿不同方向和不同速度行进的新方块。 根据我们的指示,我们假设创建并使用两个处理x和y值的数组。

这是我到目前为止:

public class DotsPanel extends JPanel { private int delay = 15; private final int SIZE = 7, IMAGE_SIZE = 3; // radius of each dot private Timer timer; private int x, y, i; private ArrayList pointList; static int [] xarray = new int [1000]; static int [] yarray = new int [1000]; Random rand = new Random(); //----------------------------------------------------------------- // Constructor: Sets up this panel to listen for mouse events. //----------------------------------------------------------------- public DotsPanel() { pointList = new ArrayList(); int [] xarray = new int [1000]; int [] yarray = new int [1000]; timer = new Timer(delay, new ReboundListener()); addMouseListener (new DotsListener()); addMouseMotionListener (new DotsListener()); setBackground(Color.gray); setPreferredSize(new Dimension(700, 500)); for(int i = 0; i < xarray.length; i++) { xarray[i] = rand.nextInt(7); yarray[i] = rand.nextInt(7); } timer.start(); } //----------------------------------------------------------------- // Draws all of the dots stored in the list. //----------------------------------------------------------------- public void paintComponent(Graphics page) { super.paintComponent(page); page.setColor(Color.BLUE); for (Point spot : pointList) { page.fillRect(spot.x-SIZE, spot.y-SIZE, 25, 25); page.drawString("Count: " + pointList.size(), 5, 15); } } //***************************************************************** // Represents the listener for mouse events. //***************************************************************** private class DotsListener implements MouseListener, MouseMotionListener { //-------------------------------------------------------------- // Adds the current point to the list of points and redraws // the panel whenever the mouse button is pressed. //-------------------------------------------------------------- public void mousePressed(MouseEvent event) { pointList.add(event.getPoint()); repaint(); } public void mouseDragged(MouseEvent event) { // initially I had two xarray and yarray in here just like in // mouseClicked // but it did not change anything when removed } //-------------------------------------------------------------- // Provide empty definitions for unused event methods. //-------------------------------------------------------------- public void mouseClicked(MouseEvent event) { xarray[i] = rand.nextInt(7); yarray[i] = rand.nextInt(7); } public void mouseReleased(MouseEvent event) {} public void mouseEntered(MouseEvent event) {} public void mouseExited(MouseEvent event) {} public void mouseMoved(MouseEvent e) {} } private class ReboundListener implements ActionListener { //-------------------------------------------------------------- // Updates the position of the image and possibly the direction // of movement whenever the timer fires an action event. //-------------------------------------------------------------- public void actionPerformed(ActionEvent event) { for (Point spot : pointList) { spot.x += xarray[i]; spot.y += yarray[i]; if (spot.x = 700) xarray[i] = xarray[i] * -1; if (spot.y = 500) yarray[i] = yarray[i] * -1; repaint(); } } } } 

但是,我对数组很困难,我确信我没有正确地做到这一点。

我不会使用数组。

相反,让Ball对象管理自己的状态。 然后你可以为每个Ball有不同的颜色,速度,大小等。 然后当Timer触发时,您只需计算新位置并重新绘制Ball

这是一个让你入门的例子:

 import java.awt.*; import java.awt.event.*; import java.awt.image.*; import java.util.*; import javax.swing.*; import javax.swing.Timer; public class BallAnimation4 { private static void createAndShowUI() { BallPanel panel = new BallPanel(500); JFrame frame = new JFrame("BallAnimation4"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setExtendedState(JFrame.MAXIMIZED_BOTH); frame.add( panel ); frame.pack(); frame.setVisible( true ); panel.startAnimation(); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { createAndShowUI(); } }); } static class BallPanel extends JPanel implements ActionListener { private ArrayList balls = new ArrayList(); public BallPanel(int ballCount) { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); setLayout( null ); setBackground( Color.BLACK ); Random random = new Random(); for (int i = 0; i < ballCount; i++) { Ball ball = new Ball(); ball.setRandomColor(true); ball.setLocation(random.nextInt(screenSize.width), random.nextInt(screenSize.height)); ball.setMoveRate(32, 32, 1, 1, true); ball.setSize(32, 32); balls.add( ball ); } } @Override public void paintComponent(Graphics g) { super.paintComponent(g); for (Ball ball: balls) { ball.draw(g); } } public void startAnimation() { Timer timer = new Timer(75, this); timer.start(); } public void actionPerformed(ActionEvent e) { move(); repaint(); } private void move() { for (Ball ball : balls) { ball.move(this); } } } static class Ball { public Color color = Color.BLACK; public int x = 0; public int y = 0; public int width = 1; public int height = 1; private int moveX = 1; private int moveY = 1; private int directionX = 1; private int directionY = 1; private int xScale = moveX; private int yScale = moveY; private boolean randomMove = false; private boolean randomColor = false; private Random myRand = null; public Ball() { myRand = new Random(); setRandomColor(randomColor); } public void move(JPanel parent) { int iRight = parent.getSize().width; int iBottom = parent.getSize().height; x += 5 + (xScale * directionX); y += 5 + (yScale * directionY); if (x <= 0) { x = 0; directionX *= (-1); xScale = randomMove ? myRand.nextInt(moveX) : moveX; if (randomColor) setRandomColor(randomColor); } if (x >= iRight - width) { x = iRight - width; directionX *= (-1); xScale = randomMove ? myRand.nextInt(moveX) : moveX; if (randomColor) setRandomColor(randomColor); } if (y <= 0) { y = 0; directionY *= (-1); yScale = randomMove ? myRand.nextInt(moveY) : moveY; if (randomColor) setRandomColor(randomColor); } if (y >= iBottom - height) { y = iBottom - height; directionY *= (-1); yScale = randomMove ? myRand.nextInt(moveY) : moveY; if (randomColor) setRandomColor(randomColor); } } public void draw(Graphics g) { g.setColor(color); g.fillOval(x, y, width, height); } public void setColor(Color c) { color = c; } public void setLocation(int x, int y) { this.x = x; this.y = y; } public void setMoveRate(int xMove, int yMove, int xDir, int yDir, boolean randMove) { this.moveX = xMove; this.moveY = yMove; directionX = xDir; directionY = yDir; randomMove = randMove; } public void setRandomColor(boolean randomColor) { this.randomColor = randomColor; switch (myRand.nextInt(3)) { case 0: color = Color.BLUE; break; case 1: color = Color.GREEN; break; case 2: color = Color.RED; break; default: color = Color.BLACK; break; } } public void setSize(int width, int height) { this.width = width; this.height = height; } } } 

由于您的数组仅包含您想要绘制的点,因此您没有任何关于每个点应移动的速度的信息。 您可以做的最好是创建一个随机数量,每次更改位置时应移动每个点。 这会产生不稳定的运动,因为每次移动一个点时距离都是随机的。

如果你想要更加恒定的速度,那么你需要创建第二个数组来包含每个点每次应该移动的距离。

每当您希望新属性对于要绘制的对象是唯一的时,这就会开始变得混乱。 这就是为什么创建具有多个属性的自定义对象的方法更容易管理。