Я просто хочу знать, как создавать простые анимации, такие как мигание, перемещение материалов на консольных приложениях С#. Есть ли специальный метод для этого?
Консольные анимации
Ответ 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);
}
}
Ответ 2
Да, для этого есть несколько методов.
В частности, вы можете посмотреть следующие методы консоли:
- SetCursorPosition (вы можете перемещать курсор и перезаписывать элементы)
- MoveBufferArea (скопируйте/вставьте поверх областей)
- ForegroundColor и BackgroundColor (изменение цвета)
Ответ 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;)