生成随机颜色的问题

时间:2013-05-18 11:32:50

标签: c# windows-phone

我想在wpf中生成一些随机颜色并将它们存储在一个数组中。

Random r;
Color[] colarr = new Color[6];
for (int i = 0; i < colarr.Length; i++)
{
   Color c=new Color();
   r=new Random();
   r.Next();
   c.R = (byte)r.Next(1, 255);
   c.G = (byte)r.Next(1, 255);
   c.B = (byte)r.Next(1, 255);
   c.A = (byte)r.Next(1, 255);
   c.B = (byte)r.Next(1, 255);          
   colarr[i] = c;
}

但是数组的所有元素都代表一种颜色。当我调试代码时,我发现每个元素都有随机颜色,但是当执行代码时(不是在调试模式下),会生成相同的颜色。这表明代码是正确的,执行时存在一些问题。

编辑:

如何增加所生成颜色的随机性?

3 个答案:

答案 0 :(得分:4)

问题是你每次运行都会创建一个随机的新实例。你应该设置一次。

Random的默认种子是系统时间,如果重复一个非常快的循环,它将是相同的;时间不会改变很多。如果您只在开始时设置它,则Random将按预期工作。

我还建议您使用r.Next(0, 256),因为这样可以为您提供0到255之间的任何值。

此外,在r.Next()定义之后调用Color c完全没必要,因为您没有使用其值。

Random r = new Random();
Color[] colarr = new Color[6];
for (int i = 0; i < colarr.Length; i++)
{
   Color c=new Color();
   c.R = (byte)r.Next(0, 256);
   c.G = (byte)r.Next(0, 256);
   c.B = (byte)r.Next(0, 256);
   c.A = (byte)r.Next(0, 256);
   //c.B = (byte)r.Next(1, 255);  This line isn't needed btw        
   colarr[i] = c;
}

答案 1 :(得分:3)

试试这个;

Random r = new Random();
Color[] colarr = new Color[6];
for (int i = 0; i < colarr.Length; i++)
{
   Color c=new Color();
   c.R = (byte)r.Next(0, 256);
   c.G = (byte)r.Next(0, 256);
   c.B = (byte)r.Next(0, 256);
   c.A = (byte)r.Next(0, 256);
   c.B = (byte)r.Next(0, 256);          
   colarr[i] = c;
}

来自 Marc's answer ;

  

每次执行new Random()时,都会使用时钟进行初始化。这个   意味着在紧密循环中,您可以多次获得相同的值。你应该保持一个   单个Random实例,并在同一个实例上继续使用Next

阅读:Random number generator only generating one random number

答案 2 :(得分:2)

如果您想要一种不同的方法来选择随机颜色,您可以使用反射。你必须根据它的调用频率来比较性能,但它可能会返回不太相似的结果。请注意,rnd值未存储在函数中,否则您将遇到与原始问题中相同的问题,即在快速连续调用方法时返回的相同值(例如来自{{ 1}}循环)。

for

您可以像这样使用

Random rnd = new Random();

private Color GetRandomColour()
{
    var colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public);
    var colors = colorProperties.Select(prop => (Color)prop.GetValue(null, null));

    int index = rnd.Next(colors.Count());

    return colors.ElementAt(index);
}