原文
https://www.cnblogs.com/jingjiangtao/p/14454766.html
效果
控制台實現的關鍵接口
設置控制台游標的函數:public static void SetCursorPosition (int left, int top); 其中left參數是列,top參數是行。
設置控制台背景色的屬性:public static ConsoleColor BackgroundColor { get; set; }
代碼實現
using System; using System.Threading; namespace Wavy { class Program { private static Cell[,] grid = new Cell[8, 50]; static void Main(string[] args) { Console.CursorVisible = false; Init(); while (true) { Update(); Thread.Sleep(50); } } private static void Init() { for (int i = 0; i < grid.GetLength(0); i++) { for (int j = 0; j < grid.GetLength(1); j++) { grid[i, j] = new Cell(); if (i == 0) { grid[i, j].Value = true; SetBlack(i, j); } else { grid[i, j].Value = false; SetBlack(i, j); } } } } private static void Update() { for (int j = 0; j < grid.GetLength(1); j++) { for (int i = 0; i < grid.GetLength(0); i++) { if (grid[i, j].Value) { grid[i, j].Value = false; SetBlack(i, j); if (grid[0, j].IsDown) { int nextRow; if (i == grid.GetLength(0) - 1) { grid[0, j].IsDown = false; nextRow = i - 1; } else { nextRow = i + 1; } grid[nextRow, j].Value = true; SetWhite(nextRow, j); } else { int nextRow; if (i == 0) { grid[0, j].IsDown = true; nextRow = i + 1; } else { nextRow = i - 1; } grid[nextRow, j].Value = true; SetWhite(nextRow, j); } break; } } if (!grid[0, j].IsStart) { grid[0, j].IsStart = true; break; } } } private static void SetWhite(int i, int j) { string fill = " "; Console.SetCursorPosition(j * fill.Length, i); Console.BackgroundColor = ConsoleColor.White; Console.Write(fill); } private static void SetBlack(int i, int j) { string fill = " "; Console.SetCursorPosition(j * fill.Length, i); Console.BackgroundColor = ConsoleColor.Black; Console.Write(fill); } } public class Cell { public bool Value { get; set; } = false; public bool IsDown { get; set; } = true; public bool IsStart { get; set; } = false; } }
grid 變量是一個二維數組,表示網格,Cell 類表示每個格子。
Cell 類的 Value 屬性表示這個格子是否應該高亮,默認為 false;IsDown 屬性表示這個格子所在列的運動方向是否向下,默認為 true;IsStart 屬性表示這個格子所在列是否已經開始運動,默認為false。
Main() 函數首先隱藏了光標,以免影響觀感;調用 Init() 函數初始化網格;之后是主循環,每次循環都調用 Udpate() 函數來更新網格,每次循環間隔默認 50 毫秒。
Init() 函數遍歷二維數組來初始化格子,並將第一行的格子設為 true,但是顏色設為黑。其他格子設為 false,顏色設為黑。
Update() 函數以列為外層循環遍歷網格。如果當前格子為 false 就跳過,如果為 true,則將當前格子設為false,顏色設為黑,接着計算這一列下一個應該點亮的格子,值設為 true,顏色設為白。計算這一列下一個應該點亮的格子,需要用到Cell的IsDown屬性和當前行數。讓所有列不同時開始才能實現波浪效果,所以在當前列的所有行遍歷完成后,判斷當前列是否已經開始,如果已經開始就繼續循環下一列,如果沒有開始,就將這一列設為開始,並結束循環。