我使用此方法获取屏幕外的随机位置,以生成所有僵尸。
public void initZombie(){
for(int i = 0; i < 100; i++){
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
int[][] spawn = {{randomXSpawn,randomYSpawn}};
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
}
}
我遇到的问题是获得随机位置的两个整数只运行一次,因此每个僵尸都会在彼此完全相同的位置产生。我怎么能让多次运行使得僵尸在不同的位置产生?我试图将它们放在run()方法中,然后它们运行两次,以便第一个僵尸在一个位置产生,然后其他99个僵尸在彼此内部的另一个位置产生。
答案 0 :(得分:2)
您正在将Math.random()
投射到一个整数值的整数。由于Math.random()
会生成0 <= x < 1
的双精度,因此总是舍入为0.这就是为什么你得到完全相同的生成位置。
您需要在演员阵容中添加括号:
int randomXSpawn = (int) (Math.random() * -300 + -50);
int randomYSpawn = (int) (Math.random() * -100 + 800);
答案 1 :(得分:1)
如果我是你,我会使用Random对象,我会调用nextInt
函数
Random rnd = new Random();
for(...)
{
int randInt = rnd.nextInt(300) //300 is the maximum
}
答案 2 :(得分:1)
您没有索引spawn
数组。其实我觉得你甚至不需要一个。试试这个
public void initZombie(int maxZombies){
Random r=new Random();
for(int i = 0; i < maxZombies; i++){
zombie.add(new Zombie(r.nextInt(MAX_X), r.nextInt(MAX_Y));
}
}
如果您以后需要调用僵尸的生成位置,可以将其保存为僵尸实例中的私有int。
原始代码也会给你负坐标,因为你乘以负常数。即使它确实有效,你最终会得到比你想要的更多的僵尸,因为new Zombie()
代码在内循环中运行。
答案 3 :(得分:1)
导致代码出现问题。正如Supericy所说的那样,你不小心意外地投出了所有的随机数,截断了它们的值,正如SJuan76在评论中提到的那样,你的for循环并没有完全正确设置。 (它有效,但它可以更清洁。)
首先,转换问题:当您将double转换为int时,小数部分将向下舍入。
int num = (int) 0.999; //num == 0
Math.random()
总是返回0到1之间的双精度,因此当强制转换为int时,它总是被截断为零。
这意味着你的行
int randomXSpawn = (int) Math.random() * -300 + -50;
的评估如下:
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomXSpawn = (int) 0.xxxx * -300 + -50;
int randomXSpawn = 0 * -300 + -50;
int randomXSpawn = -50;
要解决此问题,只需添加括号以强制在转换之前进行乘法和加法,如Supericy所说:
int randomXSpawn = (int) (Math.random() * -300 + -50);
int randomYSpawn = (int) (Math.random() * -100 + 800);
其次,for循环:这就是你现在所拥有的。它工作正常,但可以写得更清楚。
for(int i = 0; i < 100; i++) {
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
int[][] spawn = {{randomXSpawn,randomYSpawn}};
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
}
外部for循环的单次迭代会发生什么?
//int i = 0;
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
int[][] spawn = {{randomXSpawn,randomYSpawn}};
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
首先,您生成两个随机数:
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
然后,您存储这些数字,以便以后可以访问它们:
int[][] spawn = {{randomXSpawn,randomYSpawn}};
最后,你进入最后的for循环:
for(int j = 0; j < spawn.length; j++){
zombie.add(new Zombie(spawn[j][0],spawn[j][1]));
}
那里发生了什么?我们知道spawn
是一个二维数组。由于您刚刚在上面声明了它,我们也知道它的尺寸为[1][2]
。这意味着for循环将迭代一次:j = 0
时,因为在下一次迭代时j = 1
,j < spawn.length
将不再为真。
由于您声明spawn
的方式,我们知道spawn[0][0] == randomXSpawn
和spawn[0][1] == randomYSpawn
,因此内部for循环中间的行有效地执行此操作:
zombie.add(new Zombie(randomXSpawn,randomYSpawn));
这提示了一种使代码更清晰的方法:您可以删除spawn
数组和内部for循环,以便使用Zombie
和{{1}调用randomXSpawn
构造函数直接。
这就是变化的样子:
randomYSpawn
将两个更改放在一起,我们得到了这个:
for(int i = 0; i < 100; i++) {
int randomXSpawn = (int) Math.random() * -300 + -50;
int randomYSpawn = (int) Math.random() * -100 + 800;
zombie.add(new Zombie(randomXSpawn,randomYSpawn));
}
如果你不喜欢我建议的for循环重组,你不必改变它。我认为你拥有它们的方式现在可以正常工作。这只是我的意见,它很难阅读,如果你不同意,那是允许的=)。关于使用括号控制铸造的第一个变化是导致你在问题中提到的问题的原因,并且需要注意。