[英]The base System.Drawing.Color class returning only one color after a number of iterations
免責聲明:我可能包含了太多信息,所以不要被包含的信息量嚇到。
我想為 c# 控制台應用程序制作一個帶有圖形的簡單 2D 游戲。 為了了解我將如何處理圖形的基礎知識,我做了一個小項目,在其中我正在使用基本顏色 class(和庫 Colourful.Console,更多信息請訪問: http://colorfulconsole.com/ )。 只是想了解顏色表示和混合的基礎知識。
但是,我在繪制多個 colors 時遇到了問題。 由於控制台默認只能保留 16 個 colors,因此它將返回自定義 rgb colors 直到程序的第 15 次迭代(我假設為黑色保留一種顏色),然后只返回第 15 次。 有沒有辦法一遍又一遍地更改“KnownColor”之一的值,而不是填充所有這些值然后無法覆蓋新值?
我的代碼(簡化)看起來像:
class Object{
Color color;
//for simplicity, let's say that I previously had byte a, r, g, b defined here;
public Object()
{
byte[] rgba = new byte[4];
Random random = new Random();
random.NextBytes(rgba);
color = Color.FromArgb(rgba[0], rgba[1], rgba[2], rgba[3]);
//previously I assigned a = rbga[0] and so on.
}
}
class Program
{
List<Object> objects = new List<Object>();
static void Main(string[] args)
{
while(true)
{
objects.Add(new Object()); //I have some user input here, but essentially.
foreach(Object o in objects)
{
PrintColor(o.color);
PaintColor(o.color);
}
}
}
void PrintColor(Color c)
{
Console.Write("R:" + c.R + ", G:" + c.G +", B:"+ c.B + ", A:" + c.A);
}
static void PaintColor(Color c)
{
Console.BackgroundColor = Color.FromArgb(c.R, c.G, c.B);
Console.Write(" ");
Console.BackgroundColor = Color.Black;
}
}
我還嘗試制作一個應該繪制對角灰色漸變的程序(然后是全rgb漸變),但徒勞無功。
class Program
{
static void Main(string[] args)
{
GraphicsEngine.GetWindowSize();
while (true)
{
GraphicsEngine.FillWindowGradient();
Console.Clear(); //I am going to replace this with moving the cursor to 0,0
if (Console.KeyAvailable)
{
GraphicsEngine.GetWindowSize();
}
}
}
public static void FillWindowGradient()
{
int yMax = windowSize.GetLength(0);
int xMax = windowSize.GetLength(1);
for (int y = 0; y< yMax; y++)
for (int x = 0; x < xMax; x++)
{
PaintGray((byte)((y/yMax + x/xMax)*127));
}
}
public static void PaintGray(byte gray)
{
Console.BackgroundColor = Color.FromArgb(gray, gray, gray);
Console.Write(" ");
Console.BackgroundColor = Color.Black;
}
}
這個例子使用了它開始的任何一種顏色,但無法處理漸變,我認為這與第一個例子中的相同問題有關。
PS:很高興知道是否有一種“更便宜”/更快的方式來為單元格着色,而不是:
Console.BackgroundColor = Color.Argb(a, r, g, b);
Console.Write("");
您的問題是,每次生成 Object 類型的新 object 時,您都在創建一個新的Random
Object
。
僅在 .NET 框架上,由於時鍾的分辨率有限,因此使用無參數構造函數來創建不同的 Random 對象,從而創建產生相同隨機數序列的隨機數生成器。
可能的解決方案:
在您的程序 class 中創建單個隨機 object 並使用當前時間戳對其進行初始化。
Random _random = new Random((int)DateTime.UtcNow.Ticks);
將隨機的實例傳遞給 Object class。
或者,更清潔 -> 將實際隨機顏色傳遞給構造函數中的Object
。
class Object { private Color color; public Object(Color c) { color = c; } } var rgba = new byte[4]; random.NextBytes(rgba); var obj = new Object(Color.FromArgb(rgba[0], rgba[1], rgba[2], rgba[3]));
編輯:
跟進您的評論。 我已經使用您的示例在循環中生成Object
實例,生成隨機Color
。 最后,使用ToArgb
作為鍵檢查重復項。 循環運行 1000 次,沒有產生重復。 運行 100 萬次,平均約 110 次重復。
class Program
{
static List<Object> objects = new List<Object>();
static Random _random = new Random((int) DateTime.UtcNow.Ticks);
static void Main(string[] args)
{
var i = 0;
while (i<1000)
{
var rgba = new byte[4];
_random.NextBytes(rgba);
objects.Add(new Object(rgba));
i++;
}
foreach (Object o in objects)
{
PrintColor(o.color);
}
var query = objects.GroupBy(x => x.color.ToArgb())
.Where(g => g.Count() > 1)
.Select(y => y.Key)
.ToList();
Console.WriteLine($"Duplicates {query.Count}");
}
static void PrintColor(Color c)
{
Console.WriteLine("R:" + c.R + ", G:" + c.G + ", B:" + c.B + ", A:" + c.A);
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.