How to create ASCII animation in Windows Console application using C#?

爷,独闯天下 提交于 2019-12-20 08:39:20

问题


I would like it to display non-flickery animation like this awesome Linux command; sl

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

I would appreciate a small & stupid example of say ... a fly.

Thanks!


回答1:


Just use Console.SetCursorPosition for moving the cursor to a certain position, then Console.Write a character. Before each frame you have to delete the previous one by overwriting it with spaces. Heres a little example I just built:

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);
        }
    }
}

You could for instance take an animated gif, extract all single frames/images from it (see how to do that here), apply an ASCII transformation (how to do that is described here for example) and print these frame by frame like in the above code example.

Update

Just for fun, I implemented what I just described. Just try it out replacing @"C:\some_animated_gif.gif" with the path to some (not to large) animated gif. For example take an AJAX loader gif from here.

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);
        }
    }
}



回答2:


Just for fun :

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);
        }
    }
}


来源:https://stackoverflow.com/questions/2725529/how-to-create-ascii-animation-in-windows-console-application-using-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!