首页 > 解决方案 > while 循环返回一个重复的随机值而不是一个新的随机值

问题描述

我目前只是在弄乱一些代码,并且一直遇到问题。我想创建十个圆圈,然后让它们在窗口周围弹跳。我遇到了几个问题(比如当我想让圆圈从墙上反弹时,由于某种原因,400,400 窗口实际上并不是那么大。我通过检查 if 让圆圈在右侧发生碰撞x + width >= 400,但它在外面反弹除非我将 400 更改为 380?),但我的主要问题是,当我创建圆圈时,我希望它们位于不同的位置(因此它们在移动之前不会发生碰撞)。我试图得到它,以便如果一个圆圈将在另一个圆圈“内部”,然后再次创建随机 x 和 y 坐标,直到它不在另一个圆圈内。但由于某种原因,如果我把r.nextInt()在 while 循环中,它不断给我相同的值。任何人都可以帮忙吗?ps 我不介意对我犯的任何其他错误提出建议。

  package practicedots;

    import java.awt.Dimension;
    import java.awt.Graphics;
    import java.util.Random;
    import javax.swing.JFrame;
    import javax.swing.JPanel;

    public class PracticeDots extends JPanel {

        float dots[][] = new float[10][7];
        Random r = new Random();
        boolean first = true;

        float x = 0;
        float y = 0;
        float xAccel = 0;
        float yAccel = 0;
        int wall = 380;
        int width = 50;
        float radius = 0;

        float centreX = 0;
        float centreY = 0; 

        boolean collision;

        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new PracticeDots());
            f.setPreferredSize(new Dimension(400, 400));
            f.setResizable(true);
            f.pack();
            f.setVisible(true);
        }

        /**
         *
         * @return
         */
        public float[][] CreateDots() {

            if (first == true) {
                for (int i = 0; i < 10; i++) {
                    while(collision == true){
                    x = r.nextInt(300);
                    y = r.nextInt(300);
                    xAccel = r.nextFloat() / 2;
                    yAccel = r.nextFloat() / 2;
                    radius = width/2;
                    centreX = x + radius;
                    centreY = y + radius;

                    dots[i][0] = x;
                    dots[i][1] = y;
                    dots[i][2] = xAccel;
                    dots[i][3] = yAccel;
                    dots[i][4] = radius;
                    dots[i][5] = centreX;
                    dots[i][6] = centreY; 
                    bounce();
                    }

                }
                first = false;
            } else if (first == false) {

                for (int i = 0; i < 10; i++) {
                    dots[i][0] = dots[i][0] + dots[i][2];
                    dots[i][1] = dots[i][1] + dots[i][3];

                    if (dots[i][0] >= wall - width) {
                        dots[i][2] = -dots[i][2];
                    }
                    if (dots[i][1] >= wall - 20 - width) {
                        dots[i][3] = -dots[i][3];
                    }

                    if (dots[i][0] < 0) {
                        dots[i][2] = -dots[i][2];
                    }
                    if (dots[i][1] < 0) {
                        dots[i][3] = -dots[i][3];
                    }     
                    bounce();
                }
            }

            repaint();

            return dots;
        }
    //(x2-x1)^2 + (y1-y2)^2 <= (r1+r2)^2
        public void bounce() {
            for (int i = 0; i < 10; i++) {
                for (int a = 0; a < 10; a++) {
                    if (a != i) {
                        System.out.println((dots[i][0] - dots[a][0])*(dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1])*(dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]));
                        collision = (dots[i][0] - dots[a][0])*(dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1])*(dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]);
                    }
                }
            }

        }

        /**
         *
         * @param g
         */
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            for (int i = 0; i < 10; i++) {
                CreateDots();
                g.drawOval((int) dots[i][0], (int) dots[i][1], width, width);
                g.fillOval((int) dots[i][0], (int) dots[i][1], width, width);
            }
        }
    }


<!-- end snippet -->

标签: java

解决方案


有几个问题:

  1. bounce您第一次发现碰撞时应该返回,否则碰撞将设置为 true,但随后可以在 for 循环的下一次迭代中设置回 false。

  2. 在这种first == true情况下,您应该初始化collision为,true否则它将永远不会执行while循环。要么,要么将其更改为do-while.

  3. paintComponent你不应该CreateDots在 for 循环中调用,因为它会遍历所有点本身。就叫之前吧。

该代码似乎适用于这些更改(包括 400 而不是 380 的宽度):

import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class PracticeDots extends JPanel {
    float dots[][] = new float[10][7];
    Random r = new Random();
    boolean first = true;

    float x = 0;
    float y = 0;
    float xAccel = 0;
    float yAccel = 0;
    int wall = 400;
    int width = 50;
    float radius = 0;

    float centreX = 0;
    float centreY = 0;

    boolean collision;

    public static void main(String[] args) {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new PracticeDots());
        f.setPreferredSize(new Dimension(400, 400));
        f.setResizable(true);
        f.pack();
        f.setVisible(true);
    }

    public float[][] CreateDots() {
        if (first == true) {
            for (int i = 0; i < 10; i++) {
                do {
                    x = r.nextInt(300);
                    y = r.nextInt(300);
                    xAccel = r.nextFloat() / 2;
                    yAccel = r.nextFloat() / 2;
                    radius = width / 2;
                    centreX = x + radius;
                    centreY = y + radius;

                    dots[i][0] = x;
                    dots[i][1] = y;
                    dots[i][2] = xAccel;
                    dots[i][3] = yAccel;
                    dots[i][4] = radius;
                    dots[i][5] = centreX;
                    dots[i][6] = centreY;
                    bounce();
                } while (collision == true);

            }
            first = false;
        } else {
            for (int i = 0; i < 10; i++) {
                dots[i][0] = dots[i][0] + dots[i][2];
                dots[i][1] = dots[i][1] + dots[i][3];

                if (dots[i][0] >= wall - width) {
                    dots[i][2] = -dots[i][2];
                }
                if (dots[i][1] >= wall - 20 - width) {
                    dots[i][3] = -dots[i][3];
                }

                if (dots[i][0] < 0) {
                    dots[i][2] = -dots[i][2];
                }
                if (dots[i][1] < 0) {
                    dots[i][3] = -dots[i][3];
                }
                bounce();
            }
        }

        repaint();

        return dots;
    }

    public void bounce() {
        collision = false;
        for (int i = 0; i < 10; i++) {
            for (int a = 0; a < 10; a++) {
                if (a != i && !(dots[a][0] == 0 && dots[a][1] == 0)) {
                    boolean thisCollision = (dots[i][0] - dots[a][0]) * (dots[i][0] - dots[a][0]) + (dots[i][1] - dots[a][1]) * (dots[i][1] - dots[a][1]) <= (dots[i][4] + dots[a][4]) * (dots[i][4] + dots[a][4]);
//                    System.out.println("collision: "+collision+" i="+i+" a="+a);
                    if (thisCollision) {
                        collision = true;
                        return;
                    }
                }
            }
        }
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        CreateDots();
        for (int i = 0; i < 10; i++) {
            g.drawOval((int) dots[i][0], (int) dots[i][1], width, width);
            g.fillOval((int) dots[i][0], (int) dots[i][1], width, width);
        }
    }
}

推荐阅读