如何使用C#在Windows控制台应用程序中创建ASCII动画?

我希望它显示像这个令人敬畏的Linux命令的非闪烁动画; sl

我会很感激一个小而愚蠢的例子……一只苍蝇。

谢谢!

只需使用Console.SetCursorPosition将光标移动到某个位置,然后Console.Write一个字符。 在每个帧之前,您必须通过用空格覆盖它来删除前一帧。 这是我刚刚建立的一个小例子:

 class Program { static void Main(string[] args) { char[] chars = new char[] { '.', '-', '+', '^', '°', '*' }; for (int i = 0; ; i++) { if (i != 0) { // Delete the previous char by setting it to a space Console.SetCursorPosition(6 - (i-1) % 6 - 1, Console.CursorTop); Console.Write(" "); } // Write the new char Console.SetCursorPosition(6 - i % 6 - 1, Console.CursorTop); Console.Write(chars[i % 6]); System.Threading.Thread.Sleep(100); } } } 

例如,您可以使用GIF动画,从中提取所有单帧/图像(请参阅此处如何操作),应用ASCII转换(例如,如何在此处描述)并逐帧打印这些上面的代码示例。

更新

只是为了好玩,我实现了我刚才描述的内容。 试试用一些(不是大)动画gif的路径替换@"C:\some_animated_gif.gif" 。 例如,从这里获取一个AJAX加载器gif。

 class Program { static void Main(string[] args) { Image image = Image.FromFile(@"C:\some_animated_gif.gif"); FrameDimension dimension = new FrameDimension( image.FrameDimensionsList[0]); int frameCount = image.GetFrameCount(dimension); StringBuilder sb; // Remember cursor position int left = Console.WindowLeft, top = Console.WindowTop; char[] chars = { '#', '#', '@', '%', '=', '+', '*', ':', '-', '.', ' ' }; for (int i = 0; ; i = (i + 1) % frameCount) { sb = new StringBuilder(); image.SelectActiveFrame(dimension, i); for (int h = 0; h < image.Height; h++) { for (int w = 0; w < image.Width; w++) { Color cl = ((Bitmap)image).GetPixel(w, h); int gray = (cl.R + cl.G + cl.B) / 3; int index = (gray * (chars.Length - 1)) / 255; sb.Append(chars[index]); } sb.Append('\n'); } Console.SetCursorPosition(left, top); Console.Write(sb.ToString()); System.Threading.Thread.Sleep(100); } } } 

纯娱乐 :

 using System; using System.Collections.Generic; using System.Linq; using System.Threading; class Program { static void ConsoleDraw(IEnumerable lines, int x, int y) { if (x > Console.WindowWidth) return; if (y > Console.WindowHeight) return; var trimLeft = x < 0 ? -x : 0; int index = y; x = x < 0 ? 0 : x; y = y < 0 ? 0 : y; var linesToPrint = from line in lines let currentIndex = index++ where currentIndex > 0 && currentIndex < Console.WindowHeight select new { Text = new String(line.Skip(trimLeft).Take(Math.Min(Console.WindowWidth - x, line.Length - trimLeft)).ToArray()), X = x, Y = y++ }; Console.Clear(); foreach (var line in linesToPrint) { Console.SetCursorPosition(line.X, line.Y); Console.Write(line.Text); } } static void Main(string[] args) { Console.CursorVisible = false; var arr = new[] { @" ________________. ___ .______ ", @" / | / \ | _ \", @" | (-----| |----`/ ^ \ | |_) |", @" \ \ | | / /_\ \ | /", @" .-----) | | | / _____ \ | |\ \-------.", @" |________/ |__| /__/ \__\| _| `.________|", @" ____ __ ____ ___ .______ ________.", @" \ \ / \ / / / \ | _ \ / |", @" \ \/ \/ / / ^ \ | |_) || (-----`", @" \ / / /_\ \ | / \ \", @" \ /\ / / _____ \ | |\ \---) |", @" \__/ \__/ /__/ \__\|__| `._______/", }; var maxLength = arr.Aggregate(0, (max, line) => Math.Max(max, line.Length)); var x = Console.BufferWidth/2 - maxLength/2; for (int y = -arr.Length; y < Console.WindowHeight + arr.Length; y++) { ConsoleDraw(arr, x, y); Thread.Sleep(100); } } }