簡體   English   中英

基本 System.Drawing.Color class 在多次迭代后僅返回一種顏色

[英]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

來自 MSDN:

僅在 .NET 框架上,由於時鍾的分辨率有限,因此使用無參數構造函數來創建不同的 Random 對象,從而創建產生相同隨機數序列的隨機數生成器。

可能的解決方案:

  1. 在您的程序 class 中創建單個隨機 object 並使用當前時間戳對其進行初始化。

     Random _random = new Random((int)DateTime.UtcNow.Ticks);
  2. 將隨機的實例傳遞給 Object class。

  3. 或者,更清潔 -> 將實際隨機顏色傳遞給構造函數中的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM