碰撞时改变球的颜色

时间:2016-09-20 18:41:54

标签: java swing

我正在制作一个java应用程序(用于练习),其中必须有一个面板和2个按钮。

  1. 每按一次开始按钮,必须显示一个球,并根据线程移动。用户可以一直显示最多10个独立球。
  2. 按下停止按钮,每按一次停止按钮,必须移除1个球(例如,当有4个球时,用户必须按4次停止按钮才能独立移除所有球)
  3. 球的所有x和y坐标必须存储在矩阵
  4. 当一个或多个球相互碰撞时,只有碰撞的球必须从红色变为蓝色
  5. 好的,我几乎完全完成了它(从第1点到第4点),但问题就出现了。当一个球与另一个球相撞时,我的代码将所有球颜色从红色变为蓝色,而不是将碰撞球的颜色改为蓝色。我知道我的错误在于new Balls().setColor(Color.Blue),但我不知道如何只改变碰撞球。

    下面是java应用程序和代码的屏幕截图。 任何人都可以帮我解决这个问题吗?

    Printscreen:enter image description here

    源代码:

    import java.awt.Color;             
    import java.awt.Dimension;    
    import java.awt.FlowLayout;   
    import java.awt.Graphics;    
    import java.awt.event.ActionEvent;   
    import java.awt.event.ActionListener;   
    import java.util.ArrayList;  
    import java.util.List;  
    import javax.swing.JButton;    
    import javax.swing.JFrame;    
    import javax.swing.JLabel;  
    import javax.swing.JPanel;`
    
    
    public class BouncingBalls extends JPanel implements ActionListener {
    
    protected List<Ball> balls = new ArrayList<Ball>(10);
    private final Container container;
    private final DrawCanvas canvas;
    private  int canvasWidth;
    private  int canvasHeight;
    public JButton start, stop;
    int [][] coords= new int[11][2];
    int ammountOfBalls = 0;
    static Color clr= Color.RED;
    
    
    public static int random(int maxRange) {
        return (int) Math.round((Math.random() * maxRange));
    }
    
    public BouncingBalls(int width, int height) {
        setLayout(new FlowLayout());
         start= new JButton("start");
        start.addActionListener(this);
         stop= new JButton("stop");
        stop.addActionListener(this);
        add(start);
        add(stop);
        add(new JLabel(""));
        container = new Container();
        canvasWidth = width;
        canvasHeight = height;
        canvas = new DrawCanvas();
        this.setLayout(new FlowLayout());
        this.add(canvas);
        start();
    
    }
    
    public void start() {
    
        Thread t = new Thread() {
            @Override
            public void run() {
    
                while (true) {
    
                    update();
                    getPositions();
                    collisionDetection();
                    repaint();
                    try {
                        Thread.sleep(30);
                    } catch (InterruptedException e) {
                    }
                }
            }
    
            private void collisionDetection() {
                // The algorithm  that detects collision
              for(int i=0;i<ammountOfBalls;i++){
                for(int j=i+1; j<ammountOfBalls; j++){
                      if(collisionMethod(i,j)){  // my collision method
                          //HOW DO I CHANGE ONLY THE COLLIDING BALLS COLOR HERE????
                         new Ball().setColor(Color.BLUE);  // this line here changes the color of all the balls on the panel
                          System.out.println("Its a hit");
                      }
                  }
    
               }  
    
            }
    
            private void getPositions() {
                int row=0;
                for (Ball ball : balls) {
                 int x =ball.getXPosition();
                 int y =ball.getYPosition();
                 coords[row][0]=x;
                 coords[row][1]=y;
                 row++;
                }
    
            }
    
            private boolean collisionMethod(int i, int j) {
               float xd = coords[i][0]-coords[j][0];
               float yd=coords[i][1]-coords[j][1];
               float radius= new Ball().ballRadius;
               float sqrRadius= radius * radius;
               float distSqr= (xd * xd) + (yd * yd);
    
               if(distSqr <= sqrRadius)
                   return true;
    
                return false;
            }
          };
        t.start();
    }
    
    public void update() {
        for (Ball ball : balls) {
            ball.move(container);
        }
     }
    
    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == start){
            if(ammountOfBalls < 10){
                // to limit the ammount of balls to 10
                balls.add(new Ball());
                ammountOfBalls++;
           }
        }
    
        else if( e.getSource() == stop){
            if(ammountOfBalls > 0){
          ammountOfBalls --;
          balls.remove(ammountOfBalls);
    
        }
    
        }
    }
    
    class DrawCanvas extends JPanel {
    
        @Override
        public void paintComponent(Graphics g) {
    
            super.paintComponent(g);
            container.draw(g);
            for (Ball ball : balls) {
                ball.draw(g);
            }
        }
        @Override
        public Dimension getPreferredSize() {
            return (new Dimension(700, 400));
        }
    }
    
    public static void main(String[] args) {
                JFrame f = new JFrame("Bouncing Balls");
                f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
                f.setPreferredSize(new Dimension(800,500));
                f.setContentPane(new BouncingBalls(800,800));
                f.pack();
                f.setVisible(true);
        }
    
    
    public static class Ball {
    
        public int random(int maxRange) {
            return (int) Math.round(Math.random() * maxRange);
        }
    
    int x = random(700); // method to get random coords for the x-value
    int y = random(400); // method to get random coords for the y-value  ...... these are used to get random positions for the balls instead of only static
    int xMovement = 10;
    int yMovement = 10;
    int ballRadius = 20;
    int i = 0;
    
    
    public Color getColor(){
      return clr;
    }
    public Color setColor(Color color){
    clr=color;
    return clr;
    }
        public void draw(Graphics g) {
            g.setColor(getColor());
            g.fillOval(x,y,ballRadius,ballRadius);
    
        }
        public int getXPosition(){
            return x;
        }
        public int getYPosition(){
            return y;
        }
    
        public void move(Container container) {
            x += xMovement;
            y += yMovement;
    
            if (x - ballRadius < 0) {
                xMovement = -xMovement;
                x = ballRadius;
            } 
            else if (x + ballRadius > 700) {
                xMovement = -xMovement;
                x = 700 - ballRadius;
            }
    
            if (y - ballRadius < 0) {
                yMovement = -yMovement;
                y = ballRadius;
            } 
            else if (y + ballRadius > 400) {
                yMovement = -yMovement;
                y = 400 - ballRadius;
            }
        }
    }
    
    
    
    public static class Container {
        private static final int hightPanel = 800;
        private static final int widthPanel=  800;
    
        public void draw(Graphics g) {
            g.setColor(Color.WHITE);
            g.fillRect(0, 0, widthPanel, hightPanel);
        }
    }
    }
    

    `

1 个答案:

答案 0 :(得分:5)

您已将clr定义为应用程序的静态字段。当您的Ball课程调用setColor()时,您要将clr的值更改为蓝色...然后调用Ball的任何getColor()都会看到clr 1}}是蓝色的。

解决方案:不要让clr成为应用程序范围内的静态字段。在Ball类中将其定义为非静态字段,因此每个Ball都有自己的颜色。