Подтвердить что ты не робот

Консольные анимации

Я просто хочу знать, как создавать простые анимации, такие как мигание, перемещение материалов на консольных приложениях С#. Есть ли специальный метод для этого?

4b9b3361

Ответ 1

Традиционная консоль Spinner:

    static void Main(string[] args)
    {
        ConsoleSpiner spin = new ConsoleSpiner();
        Console.Write("Working....");
        while (true) 
        {
            spin.Turn();
        }
    }

public class ConsoleSpiner
{
    int counter;
    public ConsoleSpiner()
    {
        counter = 0;
    }
    public void Turn()
    {
        counter++;        
        switch (counter % 4)
        {
            case 0: Console.Write("/"); break;
            case 1: Console.Write("-"); break;
            case 2: Console.Write("\\"); break;
            case 3: Console.Write("|"); break;
        }
        Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop);
    }
}

Ответ 3

Вот мой счетчик. Цель состоит в том, чтобы программа выполняла некоторую работу, пока счетчик отображает пользователю, что что-то происходит на самом деле:

  public class Spinner : IDisposable
  {
     private const string Sequence = @"/-\|";
     private int counter = 0;
     private readonly int left;
     private readonly int top;
     private readonly int delay;
     private bool active;
     private readonly Thread thread;

     public Spinner(int left, int top, int delay = 100)
     {
        this.left = left;
        this.top = top;
        this.delay = delay;
        thread = new Thread(Spin);
     }

     public void Start()
     {
        active = true;
        if (!thread.IsAlive)
           thread.Start();
     }

     public void Stop()
     {
        active = false;
        Draw(' ');
     }

     private void Spin()
     {
        while (active)
        {
           Turn();
           Thread.Sleep(delay);
        }
     }

     private void Draw(char c)
     {
        Console.SetCursorPosition(left, top);
        Console.ForegroundColor = ConsoleColor.Green;
        Console.Write(c);
     }

     private void Turn()
     {
        Draw(Sequence[++counter % Sequence.Length]);
     }

     public void Dispose()
     {
        Stop();
     }
  }

И вы используете класс следующим образом:

     var spinner = new Spinner(10, 10);

     spinner.Start();

     // Do your work here instead of sleeping...
     Thread.Sleep(10000);

     spinner.Stop();

Ответ 4

Просто увидел это и несколько других потоков об этом и полюбил такие вещи! Я воспринял Tuukka хороший фрагмент кода и немного улучшил его, поэтому класс можно легко настроить примерно на любую последовательность вращения. Я, вероятно, добавлю некоторые аксессоры и перегруженный конструктор, чтобы отполировать его и поместить в панель инструментов ol. Забавные вещи!

class ConsoleSpinner
{
    int counter;
    string[] sequence;

    public ConsoleSpinner()
    {
        counter = 0;
        sequence = new string[] { "/", "-", "\\", "|" };
        sequence = new string[] { ".", "o", "0", "o"};
        sequence = new string[] { "+", "x" };
        sequence = new string[] { "V", "<", "^", ">" };
        sequence = new string[] { ".   ", "..  ", "... ", "...." };
    }

    public void Turn()
    {
        counter++;

        if (counter >= sequence.Length)
            counter = 0;

        Console.Write(sequence[counter]);
        Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop);
    }
}

Ответ 5

Вам нужно использовать Console.ForegroundColor, Console.BackgroundColor и Console.SetCursorPosition(int, int)

EDIT: для вдохновения Let Dance

Ответ 6

Я думал, что перезвоню с моей версией ранее указанного кода. Вот он:

class ConsoleSpinner
{
    bool increment = true,
         loop = false;
    int counter = 0;
    int delay;
    string[] sequence;

    public ConsoleSpinner(string sSequence = "dots", int iDelay = 100, bool bLoop = false)
    {
        delay = iDelay;
        if (sSequence == "dots")
        {
            sequence = new string[] { ".   ", "..  ", "... ", "...." };
            loop = true;
        }
        else if (sSequence == "slashes")
            sequence = new string[] { "/", "-", "\\", "|" };
        else if (sSequence == "circles")
            sequence = new string[] { ".", "o", "0", "o" };
        else if (sSequence == "crosses")
            sequence = new string[] { "+", "x" };
        else if (sSequence == "arrows")
            sequence = new string[] { "V", "<", "^", ">" };
    }

    public void Turn()
    {
        if (loop)
        {
            if (counter >= sequence.Length - 1)
                increment = false;
            if (counter <= 0)
                increment = true;

            if (increment)
                counter++;
            else if (!increment)
                counter--;
        }
        else
        {
            counter++;

            if (counter >= sequence.Length)
                counter = 0;
        }

        Console.Write(sequence[counter]);
        Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop);

        System.Threading.Thread.Sleep(delay);
    }
}

Добавляет задержку (к сожалению, через Thread.Sleep(), но, эй), возможность зацикливать анимацию вперед и назад (начинает отбрасываться, когда она достигает конца) и общие улучшения в целом. Наслаждайтесь!

Ответ 7

Это будет мой предпочтительный метод:

public sealed class Spinner
{
    private static Lazy<Spinner> lazy =
        new Lazy<Spinner>(()=> new Spinner());

    public static void Reset()
    {
        lazy = new Lazy<Spinner>(()=> new Spinner());
    }

    public static Spinner Instance { get { return lazy.Value; }}

    private readonly int _consoleX;
    private readonly int _consoleY;
    private readonly char[] _frames = { '|', '/', '-', '\\' };
    private int _current;

    private Spinner()
    {
        _current = 0;
        _consoleX = Console.CursorLeft;
        _consoleY = Console.CursorTop;
    }

    public void Update()
    {
        Console.Write(_frames[_current]);
        Console.SetCursorPosition(_consoleX, _consoleY);

        if (++_current >= _frames.Length)
            _current = 0;
    }
}

Вызовите Spinner.Instance.Update(), чтобы запустить счетчик в текущей позиции консоли. Любой последовательный вызов будет отображать следующий кадр в той же позиции.

Вызовите Spinner.Reset(), если вы хотите написать больше текста, а затем добавить новый счетчик в новом месте.

Ответ 8

Отличная работа с ConsoleSpinner и реализация последовательности. Спасибо за код. Я подумал о том, чтобы поделиться своим индивидуальным подходом.

public class ConsoleSpinner
{
    static string[,] sequence = null;

    public int Delay { get; set; } = 200;

    int totalSequences = 0;
    int counter;

    public ConsoleSpinner()
    {
        counter = 0;
        sequence = new string[,] {
            { "/", "-", "\\", "|" },
            { ".", "o", "0", "o" },
            { "+", "x","+","x" },
            { "V", "<", "^", ">" },
            { ".   ", "..  ", "... ", "...." },
            { "=>   ", "==>  ", "===> ", "====>" },
           // ADD YOUR OWN CREATIVE SEQUENCE HERE IF YOU LIKE
        };

        totalSequences = sequence.GetLength(0);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="sequenceCode"> 0 | 1 | 2 |3 | 4 | 5 </param>
    public void Turn(string displayMsg = "", int sequenceCode = 0)
    {
        counter++;

        Thread.Sleep(Delay);

        sequenceCode = sequenceCode > totalSequences - 1 ? 0 : sequenceCode;

        int counterValue = counter % 4;

        string fullMessage = displayMsg + sequence[sequenceCode, counterValue];
        int msglength = fullMessage.Length;

        Console.Write(fullMessage);

        Console.SetCursorPosition(Console.CursorLeft - msglength, Console.CursorTop);
    }
}

Реализация:

ConsoleSpinner spinner = new ConsoleSpinner();
spinner.Delay = 300;
while (true)
{
    spinner.Turn(displayMsg: "Loading ",sequenceCode:5);
}

Вывод:

введите описание изображения здесь

Ответ 9

Я НЕ ТО, ЧТО Я точно знаю, о чем ты. но я дам ему шанс. Я думаю, что самый большой и лучший способ вызвать "мерцающий" аффект (или то, что я считаю мигающим аффектом) - использовать возврат каретки. Лучший способ объяснить это вам - показать вам эксперимент Foo Bar. запустите новый проект и в своей основной функции попробуйте это.

Console.WriteLine("Foo/nBar");

Результат будет выглядеть следующим образом:

Foo
Bar

Но если вы используете возврат каретки.

Console.WriteLine("Foo/rBar");

Результат будет выглядеть следующим образом:

Bar

Причина в том, что Foo написан, тогда возврат каретки берет вас назад к началу строки, затем записывается Bar. Все, что вы когда-либо видели, это Бар. Это может быть полезно для "перемещения" вещей на одной линии, вместо того, чтобы переписывать одни и те же вещи снова на нескольких строках. Способ сделать прогрессирование будет состоять в использовании Console.Write(); Попробуйте это.

Console.Write("Loading");
for(int i = 0; i < 10; i++)
{
    Thread.Sleep(1000);
    Console.Write(".");
}

Выход должен быть

Loading

Последовал Fullstop каждую секунду в течение 10 секунд.

Если вы комбинируете возврат каретки с Console.Write(); вы можете писать несколько вещей в одной строке, очищать строку и писать что-то еще, или, действительно, одно и то же просто немного перемещено. (Это, конечно, нужно больше, чем я показал вам, например, запись, в которой находится "объект", который вы контролируете. Если вам нужен короткий пример, я был бы рад сделать это, просто прокомментировать и спросить меня об этом:)

Изменить: Я заметил, что люди упоминают цвет, который я забыл. Если вы делали анимацию, я предполагаю, что цвет будет обязательным. ForegroundColor и BackgroundColor находятся там, где они находятся. обратите внимание, что ForegroundColor будет применяться к следующим символам, записанным на консоль, и не будет полностью перекрашивать консоль. /Edit

Я надеюсь, что это поможет,

Skintkingle;)