2

可能重复:
随机数生成器仅生成一个随机数
随机而不是随机

这是我第一次尝试使用类和对象,我完全不知道如何处理我目前所处的情况。我正在创建一个需要在屏幕边缘生成敌人的游戏,所以我创建了一个创建 10 个对象并随机选择边缘和合适的坐标分配给它们的方法。

    private void spawner()
    {
        if (enemies.Count < 10)
        {
            int a;
            a = 10 - enemies.Count;

            for (int i = 0; i < a; i++)
            {
                int x, y, c;
                Random random = new Random();
                c = random.Next(0, 4);

                if (c == 0)
                {
                    x = random.Next(0, 839);
                    y = 1;
                }
                else if (c == 1)
                {
                    y = random.Next(0, 647);
                    x = 1;
                }
                else if (c == 2)
                {
                    x = 839;
                    y = random.Next(0, 647);
                }
                else
                {
                    y = 647;
                    x = random.Next(0, 839);
                }

                enemies.Add(new Enemy(5, 25, 3, new Point(x, y)));
                enemies[enemies.Count - 1].adjustPosition(player1.centreX, player1.centreY);
            }
        }
    }

然后我调用 Enemy 类中的方法,使坐标更靠近 Player 控制对象的中心,并创建 3 个用于绘制敌人的新点:enemys[enemies.Count - 1].adjustPosition( player1.centreX, player1.centreY);

    public class Enemy
    {
        public int enemyLife { get; set; }
        public Point enemyCentre { get; set; }
        public int enemyRadius { get; set; }
        public double enemySpeed { get; set; }
        public Point[] enemyVertices { get; private set; }

        public Enemy(int life, int radius, double speed, Point centre)
        {
            enemyLife = life;
            enemyCentre = centre;
            enemyRadius = radius;
            enemySpeed = speed;
        }

        public void adjustPosition(int centreX, int centreY)
        {
            double vx = 0;
            double vy = 0;
            double mag = 0;
            int x, y;

            if (enemyCentre.X != 0)
            {
                vx = centreX - enemyCentre.X;
                vy = centreY - enemyCentre.Y;
                mag = Math.Sqrt(vx * vx + vy * vy); // length

                vx /= mag;
                vy /= mag;

                x = (int)((double)enemyCentre.X + vx * enemySpeed);
                y = (int)((double)enemyCentre.Y + vy * enemySpeed);
                enemyCentre = new Point(x, y);

                int px, py, px2, py2, px3, py3;
                double angle;

                vx = centreX - x;
                vy = centreY - y;
                mag = Math.Sqrt(vx * vx + vy * vy); // length

                vx /= mag;
                vy /= mag;

                px = (int)((double)x + vx * 20);
                py = (int)((double)y + vy * 20);

                angle = Math.Atan2(centreY - y, centreX - x);

                px2 = (int)(px + (-30 * Math.Cos(0.785398163 + angle)));
                py2 = (int)(py + (-30 * Math.Sin(0.785398163 + angle)));

                px3 = (int)(px + (-30 * Math.Cos(-0.785398163 + angle)));
                py3 = (int)(py + (-30 * Math.Sin(-0.785398163 + angle)));

                Point[] points = new Point[3];
                points[0] = new Point(px, py);
                points[1] = new Point(px2, py2);
                points[2] = new Point(px3, py3);

                enemyVertices = points;
            }
        }
    }

问题是,当我尝试使用“开始调试”执行程序时,每个创建的对象都与最后添加到列表中的对象共享相同的中心坐标。然而,当我在将对象添加到列表之前添加断点并单步执行代码时,对象被分配了应有的随机值。此外,如果我在手动执行某些对象的代码后删除断点,手动运行的对象将包含随机值,而其余对象将共享相同的值。有谁知道是什么导致了这个问题?

4

3 回答 3

3

你的问题是新的 Random() 因为它的调用速度非常快它实际上不会是随机的,因为 .net 用于默认构造函数的随机种子不会改变(我认为他们使用了刻度或从中生成的一些哈希)

只需确保以调用之间有一段时间的方式调用 new Random(),如果您需要“快速”随机数,请使用 next()

于 2013-01-18T13:00:54.733 回答
2

那是因为您正在循环中重新创建 Random() 对象。该对象使用基于时间的种子生成伪随机数,因此在非常快速的循环中创建的几个 Random() 对象将以相同的顺序生成完全相同的值。

当您在循环中间放置断点时,会导致更改 Random() 对象的种子的延迟。

最简单的解决方案是为此方法只创建一次 Random() 对象,并在循环期间重用它。

于 2013-01-18T13:07:43.680 回答
1

Move Random random = new Random(); outside of the for loop.

It is only necessary to initialize the random number generator once. Perhaps you can make it even a static variable and initialize it only once per entire lifetime of the game. Random must be seeded. It will generate the same sequence of number for the same seed. If you do not specify seed, then current time is used as the seed. Making many calls of new Random() in a short time will create them with the same seed.

于 2013-01-18T13:13:17.207 回答