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

时间:2010-04-27 22:10:25

标签: c# animation console-application ascii-art

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

http://www.youtube.com/watch?v=9GyMZKWjcYU

我很欣赏一个小小的&愚蠢的说法......飞翔。

谢谢!

2 个答案:

答案 0 :(得分:21)

只需使用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,从中提取所有单帧/图像(请参阅如何执行此操作here),应用ASCII转换(如何对此进行描述here例如)并按照上面的代码示例逐帧打印。

<强>更新

为了好玩,我实施了我刚刚描述的内容。试试用一些(不是大)动画gif的路径替换@"C:\some_animated_gif.gif"。例如,从here获取一个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);
        }
    }
}

答案 1 :(得分:14)

只是为了好玩:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

class Program
{
    static void ConsoleDraw(IEnumerable<string> 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);
        }
    }
}