2

重複の可能性:
乱数ジェネレーターは1つの乱数のみを生成します
ランダムではありません

これはクラスとオブジェクトを使用する最初の試みであり、現在の状況をどのように処理するかについてはまったくわかりません。画面の端に敵をスポーンする必要があるゲームを作成しているので、 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つの新しいポイントを作成します。enemies[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は変更されないためです(ティックまたはそれから生成されたハッシュを使用すると思います)

新しいRandom()が呼び出しの間にある程度の時間がある方法で呼び出されていることを確認し、「高速」乱数が必要な場合はnext()を使用してください。

于 2013-01-18T13:00:54.733 に答える
2

これは、ループ内でRandom()オブジェクトを再作成しているためです。このオブジェクトは、時間ベースのシードを使用して疑似乱数を生成するため、非常に高速なループで作成された複数のRandom()オブジェクトは、まったく同じ値を同じ順序で生成します。

ループの途中にブレークポイントを設定すると、Random()オブジェクトのシードの変更に遅延が発生します。

このための最も簡単な解決策は、このメソッドに対してRandom()オブジェクトを1回だけ作成し、ループ中に再利用することです。

于 2013-01-18T13:07:43.680 に答える
1

Random random = new Random();forループの外側に移動します。

乱数ジェネレータを初期化する必要があるのは1回だけです。おそらく、それを静的変数にして、ゲームの全ライフタイムごとに1回だけ初期化することができます。ランダムにシードする必要があります。同じシードに対して同じ番号のシーケンスが生成されます。シードを指定しない場合は、現在の時刻がシードとして使用されます。短時間で新しいRandom()を何度も呼び出すと、同じシードでそれらが作成されます。

于 2013-01-18T13:13:17.207 に答える