在同一个函数内生成不同的随机值是否可行? (C#)

huangapple go评论77阅读模式
英文:

Is there a way to make different random values within the same function? (C#)

问题

以下是代码部分的中文翻译:

private void MakeShootEnemies()                                 //创建shootEnemy的函数
{
    PictureBox shootEnemy = new PictureBox();                   //初始化创建图片框
    shootEnemy.Tag = "shootEnemy";                              //为图片框添加标签
    shootEnemy.Image = Properties.Resources.RangeScientistTransparent;     //将科学家图像插入到图片框
    shootEnemy.Left = randNum.Next(100, 1820);                  //为敌人生成随机X坐标
    shootEnemyLeft = shootEnemy.Left;
    shootEnemy.Top = randNum.Next(100, 920);                    //为敌人生成随机Y坐标
    shootEnemyTop = shootEnemy.Top;
    Size size = new Size(75, 100);                              //为框设置大小
    shootEnemy.Size = size;                                     //设置框的大小
    shootEnemy.SizeMode = PictureBoxSizeMode.StretchImage;      //使图像适应图片框
    shootEnemy.BackColor = Color.Transparent;                   //应该使背景透明(不起作用,可能会删除)
  
    shootEnemiesList.Add(shootEnemy);                           //将敌人添加到敌人列表
    this.Controls.Add(shootEnemy);                              //将敌人的控件添加到表单
    player.BringToFront();                                      //将玩家置于屏幕前端
    healthBar.BringToFront();
    shootXDestination = randNum.Next(100, 1820);
    shootYDestination = randNum.Next(100, 920);
}

^创建敌人的函数^

private void ShootEnemyMovement()
{
    foreach (Control y in this.Controls)
    {               
            
        shootXDestination = randNum.Next(0, 1820);
        shootYDestination = randNum.Next(100, 920);
            
    }
}

^应该在到达前一个目的地时提供新的随机值的函数^

for (int i = 0; i < 2; i++)               //生成所需数量的shootEnemy以将总敌人数提高到10
{
    MakeShootEnemies();
    shootXDestination = randNum.Next(100, 1820);
    shootYDestination = randNum.Next(100, 920);
}

(将来数字会有所不同,但这是为了测试目的)

Random randNum = new Random();

^初始化randNum函数^

以下是移动部分的翻译:

foreach (Control y in this.Controls)                            //使shootEnemy更容易控制
{
    if (y is PictureBox && (string)y.Tag == "shootEnemy")
    {
        if ((y.Left == shootXDestination && y.Top == shootYDestination) || (y.Left == shootEnemyLeft && y.Top == shootEnemyTop))
        {
            ShootEnemyMovement();
        }

        if (y.Left > shootXDestination)
        {
            y.Left -= enemySpeed;
        }

        if (y.Left < shootXDestination)
        {
            y.Left += enemySpeed;
        }

        if (y.Top > shootYDestination)
        {
            y.Top -= enemySpeed;
        }

        if (y.Top < shootYDestination)
        {
            y.Top += enemySpeed;
        }
    }
}

希望这有助于解决您的问题。如果需要进一步的帮助,请告诉我。

英文:

I am making a prototype for a game, and am trying to make it so that the characters have spawned in a number of random places, and each will get a random X and Y coordinate that they will go to, arrive, and move to a new one. So far, I am having an issue where they all receive the same coordinates to travel to, and not getting new coordinates either. Any help would be greatly appreciated. Below is a rough code reading of what I have done so far:

private void MakeShootEnemies()                                 //creates the function for shootEnemy creation
{
    PictureBox shootEnemy = new PictureBox();                   //initialises the creation of picturebox
    shootEnemy.Tag = &quot;shootEnemy&quot;;                              //tags the picturebox
    shootEnemy.Image = Properties.Resources.RangeScientistTransparent;     //inserts the scientist image to the picture box
    shootEnemy.Left = randNum.Next(100, 1820);                  //creates a random x coordinate for the enemy to spawn on
    shootEnemyLeft = shootEnemy.Left;
    shootEnemy.Top = randNum.Next(100, 920);                    //creates a random y coordinate for the enemy to spawn on
    shootEnemyTop = shootEnemy.Top;
    Size size = new Size(75, 100);                              //creates a size for the box to be
    shootEnemy.Size = size;                                     //sets the box to said size
    shootEnemy.SizeMode = PictureBoxSizeMode.StretchImage;      //makes the image fit to the picturebox
    shootEnemy.BackColor = Color.Transparent;                   //should make the background transparent (doesnt work and will probably remove)
  
    shootEnemiesList.Add(shootEnemy);                           //adds enemy to enemies list
    this.Controls.Add(shootEnemy);                              //adds the controls for the enemy to the form
    player.BringToFront();                                      //brings the player to the front of the screen
    healthBar.BringToFront();
    shootXDestination = randNum.Next(100, 1820);
    shootYDestination = randNum.Next(100, 920);
}

^Function that creates the enemies^

private void ShootEnemyMovement()
{
    foreach (Control y in this.Controls)
            {               
            
                shootXDestination = randNum.Next(0, 1820);
                shootYDestination = randNum.Next(100, 920);
            
            }
}

^Function that should give a new random value when arriving at the previous destination^

I have also tried to do this with the randNum function within the spawning of the enemies, as shown below:

for (int i = 0; i &lt; 2; i++)               //spawns the number of shoot enemies needed to take the total enemy count to 10
{
    MakeShootEnemies();
    shootXDestination = randNum.Next(100, 1820);
    shootYDestination = randNum.Next(100, 920);
}

(number will differ in future but this is for testing purposes)

The randNum function is initialized as follows:

Random randNum = new Random();

Below is the movement itself:

foreach (Control y in this.Controls)                            //makes the shoot enemies easier to control
            {
                if (y is PictureBox &amp;&amp; (string)y.Tag == &quot;shootEnemy&quot;)
                {
                    if ((y.Left == shootXDestination &amp;&amp; y.Top == shootYDestination) || (y.Left == shootEnemyLeft &amp;&amp; y.Top == shootEnemyTop))
                    {
                        ShootEnemyMovement();
                    }

                    if (y.Left &gt; shootXDestination)
                    {
                        y.Left -= enemySpeed;
                    }

                    if (y.Left &lt; shootXDestination)
                    {
                        y.Left += enemySpeed;
                    }

                    if (y.Top &gt; shootYDestination)
                    {
                        y.Top -= enemySpeed;
                    }

                    if (y.Top &lt; shootYDestination)
                    {
                        y.Top += enemySpeed;
                    }
                }
            }

答案1

得分: 4

似乎你在每次调用时重新创建(重新初始化)Random实例,例如:

// 每次调用都会创建新的Random
// 错误的方法:每次访问属性时都会得到新的Random实例
private Random randNum => new Random();

你可以尝试使用Random.Shared,而不是randNum,让.NET为你完成工作,或者,如果你使用的是较旧版本的C#(没有Random.Shared可用),则手动创建Random,但只需创建一次:

// 只初始化一次的字段
// 不是线程安全的
private static readonly Random randNum = new Random();

或者

// 只初始化一次的只读属性
// 不是线程安全的
private static Random randNum { get; } = new Random();
英文:

It seems that you re-create (re-initialize) Random instance for each call, e.g.

// Creates new Random on each call
// Wrong approach: you are going to have new Random instance 
// each time you address the property 
private Random randNum =&gt; new Random();

You can either try to use Random.Shared instead of randNum and let .Net do the work for you, or, if you have an old version of c# (no Random.Shared available), create Random manually, but just once:

// Field which is initialized just once
// Not thread safe
private static readonly Random randNum = new Random();

or

// Readonly property which is initialized just once
// Not thread safe
private static Random randNum {get;} = new Random();

huangapple
  • 本文由 发表于 2023年3月7日 17:49:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/75660323.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定