XNA随机选择的纹理始终拾取相同的纹理
本文关键字:纹理 随机 选择 XNA | 更新日期: 2023-09-27 18:11:19
我编写这段代码是为了将大约8种不同的纹理加载到具有纹理属性的对象列表中。
我有一个名为"1.png,2.png,3.png,……,46.png"的纹理文件夹,我希望用随机选择的纹理加载8个不同的对象。
DockedFruitsList = new List<Fruit>(8);
for (int i = 0; i < 8; i++)
{
Fruit temp = new Fruit();
temp = new Fruit();
temp.Position = AvailablePositions[i];
int random=(new Random().Next(0, 4600) % 46);
temp.Texture = Content.Load<Texture2D>(@"Fruits/" + random);
DockedFruitsList.Add(temp);
}
问题是,尽管随机总是生成不同的数字,但绘制的结果总是相同的纹理,它从一次运行更改为另一次运行,但对于所有8个纹理来说总是相同的
spriteBatch.Begin();
for (int i = 0; i < DockedFruitsList.Count; i++)
{
spriteBatch.Draw(DockedFruitsList[i].Texture, DockedFruitsList[i].Position, Color.White);
}
spriteBatch.End();
试试这个:
for (int i = 0; i < 100; i++)
Console.WriteLine(new Random().Next(0, 10));
你很可能会得到这样的输出:
5
5
5
.
.
.
这是因为Random
类的种子是用基于时间的值初始化的。如果在同一时间点附近初始化Random
类的许多实例,那么它们最终都将使用相同的种子,因此它们将产生的值都将相同。
您真正想要做的是创建一个Random
实例,并将其用于所有随机值。生成的值彼此之间没有关系:
var r = new Random();
for (int i = 0; i < 100; i++)
Console.WriteLine(r.Next(0, 10));
输出:
2
8
0
.
.
.
来自msdn:
随机数的生成从种子值开始。如果重复使用相同的种子,则会生成相同的数字序列。默认情况下,Random类的无参数构造函数使用系统时钟生成其种子值
它使用的系统时钟只会每隔几毫秒改变一次值,所以如果你很快调用new Random()
,它就会被设定为相同的数字,因此对Next...
的调用会产生相同的结果。
请注意,如果您对其进行了调试,逐步执行代码会给系统时钟提前的时间,因此,除非它在没有中断/逐步执行的情况下运行循环,否则您不会得到错误
创建一次Random
对象,然后重用它(注意,我现在正在将random
转换为字符串,并且我也在random上调用了一个不同的方法(:
var rand = new Random();
DockedFruitsList = new List<Fruit>(8);
for (int i = 0; i < 8; i++)
{
Fruit temp = new Fruit();
temp = new Fruit();
temp.Position = AvailablePositions[i];
int random=(rand.Next(46) + 1);
temp.Texture = Content.Load<Texture2D>(@"Fruits/" + random.ToString());
DockedFruitsList.Add(temp);
}
new Random().Next(0, 4600)
意味着您每次都初始化rng(可能使用相同的种子?(将新成员移动到方法之外(静态成员或类似成员(。
Random
按时间(GetTickCount()
(播种,时间仅每隔几毫秒变化一次。因此,在该间隔内创建的所有随机实例都将返回相同的序列。正确的做法是只在循环之外创建一个Random
实例。
DockedFruitsList = new List<Fruit>(8);
Random rand = new Random();
for (int i = 0; i < 8; i++)
{
Fruit temp = new Fruit();
temp = new Fruit();
temp.Position = AvailablePositions[i];
int random=(rand.Next(1, 46));
temp.Texture = Content.Load<Texture2D>(@"Fruits/" + random);
DockedFruitsList.Add(temp);
}
查看Revisiting random了解更多详细信息。
也没有理由使用rand.Next(0, 4600)%46
。您可以直接使用rand.Next(0,46)
。
请注意,此代码仍将返回重复的条目。如果你想完全避免这种情况,你可以使用:
Random rand=new Random();
foreach(int randomFruid in Range(1,46).Shuffle(rand).Take(8))
{
...
}
使用来自Is的Shuffle
使用Random和OrderBy是一个好的shuffle算法吗?