java - 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 -->
解决方案
有几个问题:
在
bounce
您第一次发现碰撞时应该返回,否则碰撞将设置为 true,但随后可以在 for 循环的下一次迭代中设置回 false。在这种
first == true
情况下,您应该初始化collision
为,true
否则它将永远不会执行while
循环。要么,要么将其更改为do-while
.在
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);
}
}
}
推荐阅读
- c# - 将值从表单标签传递到操作方法不起作用
- python - 无法安装 skbuild
- wordpress - 显示所有帖子并根据观看次数最多对它们进行排序
- error-handling - Gerrit 错误说无法检查权限
- spring-boot - 无法将两个 Neo4j 实例与 Spring boot/Spring 数据 neo4j 一起使用
- c# - 使用 ReactiveUI 禁用和启用文本字段更改上的按钮
- c++ - 如何检查 cmake 正在使用什么编译器?
- c++ - sscanf 在 MSVC++ 15+ 中是否发生了变化?
- c# - 使用 FileUpload 控件在 asp.net c# 中获取文件的完整路径
- javascript - 暂停后的 Youtube Javascript API 回调