我只想知道如何创建简单的动画,如闪烁,移动C#控制台应用程序中的东西。有没有特别的方法呢?控制台动画
控制台动画
回答
你需要使用Console.ForegroundColor
,Console.BackgroundColor
和Console.SetCursorPosition(int, int)
编辑:为灵感,Let's Dance
我很想看到Lets Dance动画的框架作为文本,所以我们可以实现一个像Console Spinner这样的动画。 – TaterJuice 2017-03-10 21:35:49
是的,有quite a few methods这一点。
特别是,你可能想看看下面的控制台方法:
- SetCursorPosition(可以左右移动光标,并覆盖元素)
- MoveBufferArea(复制/粘贴在区域的顶部)
- ForegroundColor和BackgroundColor(改变颜色)
我也不太相信,我正是你在说什么知道的。但我会给它一个镜头。 我认为导致“眨眼”影响(或我认为闪烁的影响)的最大和最好的方法是使用回车。 向您解释它的最佳方式是向您展示Foo Bar实验。 开始一个新的项目,并在你的主要功能,试试这个。
Console.WriteLine("Foo/nBar");
输出将看起来像这样
Foo
Bar
但是如果你使用一个回车。
Console.WriteLine("Foo/rBar");
输出将看起来像这样
Bar
的原因是,富写入,然后回车带你回线的起点,然后将其棒被写入。你看到的只是酒吧。 这可能有助于在一行上“移动”事物,而不是在多行上再次重写相同的事物。 执行进程的一种方法是使用Console.Write(); 试试这个。
Console.Write("Loading");
for(int i = 0; i < 10; i++)
{
Thread.Sleep(1000);
Console.Write(".");
}
输出应该
Loading
随之而来的是句号每秒10秒。
如果将Carriage return与Console.Write();函数,你可以在单行上写多个东西,清除行并写入其他东西,或者确实,只是略微移动了相同的东西。 (这当然需要比我向你展示的更多,比如记录你所控制的“对象”在哪里。如果你想要一个简短的例子,我会很乐意做一个,只是评论和问我:)
编辑: 我注意到人们提到的颜色,我忘了。如果你在做动画,我猜颜色是必须的。 ForegroundColor和BackgroundColor是它的位置。 注意ForegroundColor将应用于写入控制台的下一个字符,它不会完全重新着色控制台。 /编辑
我希望这有助于
Skintkingle;)
不幸的是,这并不适用于大多数情况。你不能用\ r上去,所以你非常有限,没有使用Console.SetCursorPosition – 2009-12-17 17:51:09
当然是啊。 我不再在控制台上玩耍了,我忘记了最明显的东西。 :) – Skintkingle 2009-12-17 17:56:32
传统控制台微调:
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);
}
}
刚看到这和一些其他线程关于它,喜欢这种东西!我拿了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);
}
}
我以为我会用我以前列出的代码版本。那就是:
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()
但是,嘿),能够循环动画向前和向后(启动时它击中年底反转),以及整体普遍改善。请享用!
这将是我的首选方法:
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()
。
这是我的微调。它的目的是为了有一个程序做了一些工作,而微调显示给用户的东西是实际发生的事情:
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();
伟大的工作, 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);
}
输出:
我把anwser从@ThisGuy和修改它了一点,但我注意到,有时该行未被清除,因为它应该。
static void Main(string[] args)
{
Console.WriteLine("1");
var tddf = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd 4343",() =>
{
return "";
});
Console.WriteLine("2");
var tdd = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd",() =>
{
Thread.Sleep(1);
return "";
});
Console.WriteLine("3");
var t = XConsole.BusyIndicator("test 1 trtg vdgd",() =>
{
Thread.Sleep(1000);
return "";
});
Console.WriteLine("4");
var xt = XConsole.BusyIndicator("test 2",() =>
{
Thread.Sleep(2000);
return "";
});
var xtx = XConsole.BusyIndicator("test 2 csds fsd fdsf ds s",() =>
{
Thread.Sleep(2000);
return "";
});
Console.WriteLine("5");
Thread.Sleep(4000);
}
微调类:
public class Spinner : IDisposable
{
private const string Sequence1 = @"/-\|";
private const string Sequence3 = @".o0o";
private const string Sequence2 = @"<^>v";
private const string Sequence4 = @"#■.";
private const string Sequence5 = @"▄▀";
private const string Sequence = @"└┘┐┌";
private string BusyMessage = "";
private int counter = 0;
private readonly int delay;
private bool active;
private readonly Thread thread;
public Spinner(int delay = 200)
{
this.delay = delay;
thread = new Thread(Spin);
}
public void Start()
{
active = true;
Console.CursorVisible = false;
if (!thread.IsAlive)
{
thread.Start();
}
}
public void Start(string busyMessage)
{
BusyMessage = busyMessage;
Start();
}
public void Stop()
{
active = false;
Console.CursorVisible = true;
ClearCurrentConsoleLine();
BusyMessage = "";
}
private static void ClearCurrentConsoleLine()
{
int currentLineCursor = Console.CursorTop;
Console.SetCursorPosition(0, Console.CursorTop);
Console.Write(new string(' ', Console.WindowWidth));
Console.SetCursorPosition(0, currentLineCursor);
}
private void Spin()
{
while (active)
{
Turn();
Thread.Sleep(delay);
}
}
/// <summary>
/// Draws the busy indicator
/// </summary>
/// <param name="c">if empty char, then clear screen</param>
private void Draw(char c)
{
int left = Console.CursorLeft;
int top = Console.CursorTop;
Console.Write('[');
Console.ForegroundColor = ConsoleColor.Green;
Console.Write(c);
Console.ForegroundColor = ConsoleColor.Gray;
Console.Write(']');
if (!string.IsNullOrEmpty(BusyMessage))
{
Console.Write(" " + BusyMessage);
}
//reset cursor position
Console.SetCursorPosition(left, top);
}
private void Turn()
{
Draw(Sequence[++counter % Sequence.Length]);
}
public void Dispose()
{
Stop();
}
}
我的控制台类:
public static class XConsole {
public static T BusyIndicator<T>(Func<T> action)
{
T result;
using (var spinner = new Spinner())
{
spinner.Start();
result = action();
spinner.Stop();
}
return result;
}
public static T BusyIndicator<T>(string content, Func<T> action)
{
T result;
using (var spinner = new Spinner())
{
spinner.Start(content);
result = action();
spinner.Stop();
}
return result;
}
}
为什么我有时会看到这样的结果?
1
2
3 st 0 trtg fdfdfvdgd ]
4
[└] test 2 csds fsd fdsf ds s
看起来像Dispose没有触发?或者一个新的Task
alredy开始了?
它应该是这样的:
1
2
3
4
[└] test 2 csds fsd fdsf ds s
UPDATE:
我加入ClearCurrentConsoleLine();
,改变了Draw
方法,这个固定的问题。
我会认为它不是线程安全的,但如何解决这个问题? – Rumplin 2018-02-24 17:21:53
前两次睡眠小于初始延迟(200 ms)。这就是为什么第三行是第一个显示消息的原因。你的睡眠在回调中发生,所以它们全部被并行启动。您正在打印当前控制台位置的状态,该位置在执行期间发生更改。 Hardcode left = 0,top = 5,你会看到你想要的输出。说了,我不太明白你在做什么。 – ThisGuy 2018-02-25 18:23:56
从网络共享中读取文件。有了这个用户会看到发生了一些事情。它正在读取大量文件,并且需要一段时间来处理网络共享。这里的'Thread.Sleep'模拟这个。 – Rumplin 2018-02-26 19:19:51
- 1. 控制台cout动画 - C++
- 2. 控制动画
- 3. 在控制台上绘制HTML5画布
- 4. jQuery控制动画
- 5. ajax动画控制
- 6. 渲染滚动控制台
- 7. 在控制台启动
- 8. 控制台自动前缀?
- 9. 控制台启动菜单
- 10. 动态控制台primefaces 4.0
- 11. 按钮控制动画
- 12. 用Jquery控制GIF动画?
- 13. 控制动画速度
- 14. 用JS控制CSS动画?
- 15. 控制重用动画
- 16. 控制停止其动画
- 17. 动画控制旋转
- 18. jQuery动画控制序列
- 19. CSS动画速度控制
- 20. javascriptpresspress来控制动画
- 21. 如何控制Unity动画?
- 22. .Net无法启动控制台的控制台应用程序
- 23. 为什么这个Java控制台动画如此糟糕?
- 24. PowerShell:控制台和SetCursorPosition中的角色动画变得疯狂
- 25. ScrollReveal.js v2.3.2加载,没有控制台错误,但没有动画
- 26. 如何修复这个控制台旋转动画的孔
- 27. nam(网络动画)控制台没有在ns2中登录
- 28. 刷新页面后角度动画控制台错误
- 29. Firebase控制台到Google控制台
- 30. Rails3 irb控制台vs rails控制台?
+1喜欢这个问题,IMMD =) – 2009-12-17 17:41:16