【.NET】控制檯應用程式的各種互動玩法

2023-12-18 06:01:12

老周是一個不喜歡做介面的碼農,所以很多時候能用控制檯互動就用控制檯互動,既方便又佔資源少。有大夥伴可能會說,控制檯全靠打字,不好互動。那不一定的,像一些選項類的互動,可以用鍵盤按鍵(如方向鍵),可比用滑鼠快得多。當然了,要是要觸控的話,是不太好用,只能做UI了。

關於控制檯互動,大夥伴們也許見得最多的是進度條,就是輸出一行但末尾不加 \n,而是用 \r 回到行首,然後輸出新的內容,這樣就做出進度條了。不過這種方法永遠只能修改最後一行文字。

於是,有人想出了第二種方案——把要輸出的文字存起來(用二維陣列,啥的都行),每次更新輸出時把螢幕內容清空重新輸出。這就類似於視窗的重新整理功能。缺點是文字多的時候會閃屏。

綜合來說,區域性覆蓋是最優方案。就是我要修改某處的文字,我先把遊標移到那裡,覆蓋掉這部分內容即可。這麼一來,咱們得了解,在控制檯程式中,遊標是用行、列定位的。其移動的單位不是畫素,是字元。比如 0 是第一行文字,1 是第二行文字……對於列也是這樣。所以,(2, 4) 表示第三行的第五個字元處。這個方案是核心原理。

當然了,上述方案只是程式展示給使用者看的,若配合使用者的鍵盤輸入,互動過程就完整了。

下面給大夥伴們做個演示,以便了解其原理。

internal class Program
{
    static void Main(string[] args)
    {
        // 我們先輸出三行
        Console.WriteLine("====================");
        Console.WriteLine("你好,小子");
        Console.WriteLine("====================");

        // 我們要改變的是第二行文字
        // 所以top=1
        int x = 10;
        do
        {
            // 重新定位遊標
            Console.SetCursorPosition(0, 1);
            Console.Write("離爆炸還剩 {0} 秒", x);
            Thread.Sleep(1000);
        }
        while ((--x) >= 0);

        Console.SetCursorPosition(0, 1);
        Console.Write("Boom!!");
        Console.Read();
    }
}

SetCursorPosition 方法的簽名如下:

public static void SetCursorPosition(int left, int top);

left 引數是指遊標距離控制檯視窗左邊沿的位移,top 引數指定的是遊標距離視窗上邊沿的位移。因此,left 表示的是列,top 表示的是行。都是從 0 開始的。

你得注意的是,在覆蓋舊內容的時候,要用 Write 方法,不要呼叫 WriteLine 方法。你懂的,WriteLine 方法會在末尾產生換行符,那樣會破壞原有文字的佈局的,覆寫後會出現N多空白行。

咱們看看效果。

 

生成點陣圖時,尺寸不要太大,不然很佔螢幕。畢竟控制檯是以字元來計量的,不是畫素。