Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#比Console.Write()更快的东西?_C# - Fatal编程技术网

C#比Console.Write()更快的东西?

C#比Console.Write()更快的东西?,c#,C#,我正在制作一个游戏,用Console重新绘制游戏场不是很好。Write()有什么方法可以让我更快地重写整个游戏场而不让它看起来“滞后”吗?游戏场中几乎所有的东西都在移动,但只有与0不同的元素才有对象。。(你可以在这里查看完整的代码,如果我的描述不够,你可以看看我在说什么) for(int Y=0;Y

我正在制作一个游戏,用Console重新绘制游戏场不是很好。Write()有什么方法可以让我更快地重写整个游戏场而不让它看起来“滞后”吗?游戏场中几乎所有的东西都在移动,但只有与0不同的元素才有对象。。(你可以在这里查看完整的代码,如果我的描述不够,你可以看看我在说什么)

for(int Y=0;Y
另一种方法是使用链接中指定的API调用


通过将for循环中的输出缓冲到StringBuilder中,并在每个for循环后输出,也可以获得轻微的性能。这可能不是必需的,这取决于您想用程序实现什么。

如果您隐藏输出cmd窗口,windows不会重新绘制它,并且您的应用程序运行速度比在屏幕上打开时快


如果这只是一个调试问题,您可以简单地最小化窗口并看到性能的小幅度提高。

基本上有两种方法:渲染更少和渲染更快

“渲染较少”(Render less)通常比较棘手,但也往往不太密集。经典的例子是Carmack热衷的游戏——电脑没有勇气一次重播整个屏幕,所以Carmack确保只有屏幕上真正改变的部分被重画。在您的情况下,这可以像检查新屏幕和旧屏幕一样简单(当然不使用
控制台
方法)-根据您正在编写的游戏类型,这可以为您节省大量工作

渲染速度更快通常更容易。在过去,通常的方法是直接访问输出缓冲区——而不是将游戏场放在单独的内存中,而是直接放在图形卡中——当然,它能够根据需要快速地重新绘制整个屏幕,因为否则你在CRT屏幕上看不到太多。此选项仍然可以作为向后兼容性访问,因此如果您使用Turbo Pascal编写应用程序,您仍然可以使用它,但在C#中它并不是那么容易访问的。有一个选项可以先在
StringBuilder
中呈现整个屏幕,然后在
控制台中呈现整个屏幕。一次编写
。它的速度会快一点,但它并不完全是恒星
char[]
将为您提供额外的性能点-您可以将您的游戏场直接表示为
char[][]
,这样您就不必每次更改内容时都重新创建
StringBuilder
-您只需
控制台。为每个游戏场行编写一次

当然,你可以简单地在变化发生时写下它们;这取决于你正在写的游戏,它的范围可以从“小到大”到“相当难,看起来不好”。由于控制台的缓冲区可能大于窗口大小,您甚至可以将其绘制到缓冲区的隐藏部分,然后使用
console.MoveBufferArea
一次绘制整个更改-这通常称为“backbuffering”。不过,我不确定它是否好看——现在的控制台窗口允许您在缓冲区中滚动,这对您的用例来说可能是有害的

仍然有很多方法可以更快地访问控制台缓冲区,但不能完全停留在.NET中,您需要使用p/Invokes。关于这个话题,这里有一个很好的答案-。在现代系统中,这几乎相当于使用一个后缓冲区并一次“绘制”所有内容—速度惊人。同样,你可以直接使用你的游戏数据的后缓冲区——它在20-30年前起作用,现在仍然起作用;这是在有限的资源下游手好闲的好做法。你能写一个游戏,真正使用控制台文本缓冲区的一切,或至少几乎一切?玩这样的东西很有趣;你可以写一大堆这样的游戏,包括俄罗斯方块或Lode Runner之类的游戏。当然,这只适用于Windows,因此,如果您想支持其他系统,这就要复杂得多


最后,您可以编写自己的控制台(或者更好,使用已经编写和测试过的控制台)。如果你想随着时间的推移继续面对更大的挑战,这是一个很好的实践,它将允许你随着时间的推移使用更强大的技术。典型的例子是像《矮人堡垒》这样的游戏——仍然是基于文本的,仍然是类似于控制台的,但实际上是使用SDL等技术以图形方式绘制的。这不仅在现代系统上要快得多(因为你没有简单的方法直接访问文本缓冲区),而且它还提供了一个选择,可以很容易地切换到图形平铺游戏。这是通向酷东西的阶梯上的另一块垫脚石:)

只是不要重新绘制整个屏幕,只更改部分我以为这就是我正在做的,但显然我不是,刚才我注意到我最后一个“如果”是不必要的
for (int Y = 0; Y < playfield.GetLength(0); Y++)
{
    for (int X = 0; X < playfield.GetLength(1); X++)
    {
        //destroying the row when it reaches the top
        if (playfield[0, X] != 0)
        {
            for (int i = 0; i < playfield.GetLength(1); i++)
            {
                playfield[0, X] = 0;
                Console.SetCursorPosition(X, 0);
                Console.Write(" ");
            }
        }
        if (playfield[Y, X] == 3)
        {
            playfield[Y - 1, X] = 3;
            playfield[Y, X] = 0;
        }
        else if (playfield[Y, X] == 1)
        {
            Console.SetCursorPosition(X, Y - 1);
            Console.Write("=");
            playfield[Y - 1, X] = 1;
            Console.SetCursorPosition(X, Y);
            Console.Write(" ");
            playfield[Y, X] = 0;
        }
        else if (playfield[Y, X] == 0)
        {
            Console.SetCursorPosition(X, Y);
            Console.Write(" ");
        }
    }
}
[DllImport("kernel32.dll")]
static extern void OutputDebugString(string lpOutputString);