0

我使用这种方法来获取屏幕外的随机位置以生成所有僵尸。

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 个僵尸在彼此内部的另一个位置生成。

4

4 回答 4

2

您正在转换Math.random()为一个整数,该整数会降低该值。由于Math.random()生成一个 double 0 <= x < 1,它总是四舍五入为 0。这就是为什么你得到完全相同的生成位置。

您需要在演员表中添加括号:

int randomXSpawn = (int) (Math.random() * -300 + -50);
int randomYSpawn = (int) (Math.random() * -100 + 800);
于 2013-04-24T22:04:00.723 回答
1

如果我是你,我会使用Random对象,然后调用nextInt函数

Random rnd = new Random();

for(...)
{
    int randInt = rnd.nextInt(300) //300 is the maximum
}
于 2013-04-24T22:01:28.467 回答
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()代码在内部循环中运行。

于 2013-04-24T22:05:04.123 回答
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是一个二维数组。由于您刚刚在上面声明了它,我们也知道它有 dimensions [1][2]。这意味着 for 循环将迭代一次: when j = 0,因为j = 1下一次迭代时的whenj < spawn.length将不再为真。

由于您声明 的方式spawn,我们知道spawn[0][0] == randomXSpawnand spawn[0][1] == randomYSpawn,因此内部 for 循环中间的行有效地执行了此操作:

        zombie.add(new Zombie(randomXSpawn,randomYSpawn));

这建议了一种使代码更清晰的方法:您可以删除spawn数组和内部 for 循环,以便使用and直接调用Zombie构造函数。randomXSpawnrandomYSpawn

这就是变化的样子:

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(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 循环重组,你不必改变它。我认为您现在拥有它们的方式可以正常工作。这只是我的观点,它很难阅读,如果你不同意,那是允许的 =)。但是,关于使用括号来控制强制转换的第一个变化是导致您在问题中提到的问题的原因,并且需要加以注意。

于 2013-04-24T22:33:08.367 回答