我正在制作游戏,使用 Console.Write() 重绘游戏区域不是很好,有什么方法可以更快地重写整个游戏区域,而不会使它看起来“滞后”?游戏场中几乎所有的东西都在移动,但只有在元素不为 0 时才会有对象。(您可以在此处查看完整代码 http://pastebin.com/TkPd37xD 如果我的描述不够,请查看我在说什么)
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(" ");
}
}
}
最佳答案
基本上有两种方法:渲染更少,渲染更快。
渲染较少通常更棘手,但也往往不那么密集。典型的例子是 Carmack 的 Keen 游戏——PC 没有勇气一次重新渲染整个屏幕,所以 Carmack 确保只有屏幕上实际发生变化的部分才被重绘。在您的情况下,这可以像检查新屏幕和旧屏幕一样简单(当然不使用 Console 方法)- 根据您正在编写的游戏类型,这可以节省你的工作量很大。
渲染速度越快通常越容易。过去通常的方法是直接访问输出缓冲区——而不是将游戏场放在单独的内存中,而是直接在图形卡中——这完全能够根据需要快速重绘整个屏幕,当然,否则您将永远不会在 CRT 屏幕上看到太多内容。此选项仍然可以作为向后兼容性访问,因此如果您使用 Turbo Pascal 编写应用程序代码,您仍然可以使用它,但在 C# 中并不是那么容易访问。可以选择先在 StringBuilder 中渲染整个屏幕,然后在 Console.Write 中同时渲染整个屏幕。它会快很多,但并不完全是恒星。 char[] 将让您获得额外的性能点 - 您可以将您的游戏场直接表示为 char[][] 然后您不必重新创建 StringBuilder 每次你改变一些东西 - 你只需要 Console.Write 每条 playfield 行一次。
当然,您可以在更改发生时立即将更改写下来;根据您正在编写的游戏,这可以从“微不足道但结果很好”到“相当困难且看起来不好看”不等。由于控制台的缓冲区可以大于窗口大小,您甚至可以将其绘制到缓冲区的隐藏部分,然后使用 Console.MoveBufferArea 一次绘制整个变化- 这通常称为“反向缓冲”。不过,我不确定它是否看起来不错 - 现在的控制台窗口允许您在缓冲区中滚动,这对您的用例来说可能是有害的。
仍然有一些方法可以更快地访问控制台缓冲区,但不能完全停留在 .NET 中 - 您需要使用 P/Invokes。关于这个主题的一个很好的答案在这里 - How can I write fast colored output to Console? .在现代系统上,这几乎等同于使用后台缓冲区并一次“绘制”它——速度快得令人难以置信。同样,您可以直接为您的游戏数据使用后台缓冲区 - 它在 20-30 年前有效,今天仍然有效;使用有限的资源是一种很好的做法。您能否编写一款真正只对所有内容或至少几乎所有内容使用控制台文本缓冲区的游戏?玩那样的东西很有趣;你可以编写大量这样的游戏,包括俄罗斯方 block 或 Lode Runner 等游戏。当然,这只能在 Windows 上运行,所以如果你想支持其他系统,就比较棘手了。
最后,您可以只编写自己的控制台(或者更好的是,使用某人已经编写和测试过的控制台)。如果你想随着时间的推移继续迎接更大的挑战,这是一个很好的做法,它会让你随着时间的推移使用更强大的技术。典型的例子是像 Dwarf Fortress 这样的游戏——仍然基于文本,仍然类似于控制台,但实际上使用 SDL 等技术以图形方式绘制。这不仅在现代系统上快得多(因为您没有直接访问文本缓冲区的简单方法),它还提供了相当容易地切换到图形平铺游戏的选项。这是冷却东西的阶梯上的又一 block 垫脚石:))
关于C# 比 Console.Write() 更快的东西?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29920056/
我好像记得Lua有类似Ruby的method_missing的东西。还是我记错了? 最佳答案 表的metatable的__index和__newindex可以用于与Ruby的method_missing相同的效果。 关于ruby-难道Lua没有和Ruby的method_missing相媲美的东西吗?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/7732154/
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,
我找到了这样的东西:Rails:Howtolistdatabasetables/objectsusingtheRailsconsole?这一行没问题:ActiveRecord::Base.connection.tables并返回所有表但是ActiveRecord::Base.connection.table_structure("users")产生错误:ActiveRecord::Base.connection.table_structure("projects")我认为table_structure不是Postgres方法。如何列出Postgres数据库的Rails控制台中表中的所有
我正在使用ruby1.8.7。p=lambda{return10;}deflab(block)puts'before'putsblock.callputs'after'endlabp以上代码输出为before10after我将相同的代码重构到这里deflab(&block)puts'before'putsblock.callputs'after'endlab{return10;}现在我收到LocalJumpError:意外返回。对我来说,这两个代码都在做同样的事情。是的,在第一种情况下我传递了一个过程,在第二种情况下我传递了一个block。但是&block将该block转换为pro
在尝试解决“网格上的路径”问题时,我编写了代码defpaths(n,k)p=(1..n+k).to_ap.combination(n).to_a.sizeend代码工作正常,例如ifn==8andk==2代码返回45,这是正确的路径数。但是,当使用较大的数字时,代码非常慢,我正在努力想出如何加快这个过程。 最佳答案 与其构建组合数组只是为了计算它,不如编写function定义组合的数量。我敢肯定还有包含此功能和许多其他组合函数的gem。请注意,我使用的是gemDistribution对于Math.factorial方法,但这是另一种
我如何做Ruby方法"Flatten"RubyMethod在C#中。此方法将锯齿状数组展平为一维数组。例如:s=[1,2,3]#=>[1,2,3]t=[4,5,6,[7,8]]#=>[4,5,6,[7,8]]a=[s,t,9,10]#=>[[1,2,3],[4,5,6,[7,8]],9,10]a.flatten#=>[1,2,3,4,5,6,7,8,9,10 最佳答案 递归解决方案:IEnumerableFlatten(IEnumerablearray){foreach(variteminarray){if(itemisIEnume
我最近从C#转向了Ruby,我发现自己无法制作可折叠的标记代码区域。我只是想到做这种事情应该没问题:classExamplebegin#agroupofmethodsdefmethod1..enddefmethod2..endenddefmethod3..endend...但是这样做真的可以吗?method1和method2最终与method3是同一种东西吗?还是有一些我还没有见过的用于执行此操作的Ruby惯用语? 最佳答案 正如其他人所说,这不会改变方法定义。但是,如果要标记方法组,为什么不使用Ruby语义来标记它们呢?您可以使用