Invasion - C# 风格






4.76/5 (36投票s)
这款“太空侵略者”风格的游戏使用新的DirectX9移植到了C#,以展示托管DirectX的便捷性。
引言
DirectX多年来发生了很大的变化,新的DirectX 9提供了一些以前版本从未有过的新功能。DX9提供了增强3D操作的新功能。但一个重大改变是增加了托管DirectX,这样您就可以使用.Net语言创建应用程序,同时仍然可以连接到DirectX。这无需绕过COM互操作性问题。DirectX9直接支持托管代码,并从长远来看使DirectX/C#开发者的生活更加简单。托管DirectX类包含一组DirectDraw类,用于2D操作。这个2D接口不是DirectDraw的新版本,而是用于访问DirectDraw7接口的包装器。这对于许多仍想制作2D游戏并同时使用.NET语言的开发人员来说很有用。
DirectX SDK可从Microsoft获取,网址为http://msdn.microsoft.com/directx/
好了,介绍完毕,让我们开始编写代码吧…
图形
我做的第一件事是将BMP文件转换为PNG。我这样做的原因有几个。首先是PNG文件更小,因此直接将其嵌入到可执行文件中不会像位图那样显著增加文件大小。第二个原因是演示可以使用其他文件格式来创建表面。这并非DirectX 9的直接功能,但有C#类可以正确读取数据。我最初转换为JPG,但质量设置太低,图像看起来不太好。
处理像Draw
这样的方法调用的错误代码也与DX8不同。没有返回错误代码,只有try/catch来获取错误。
try
{
back.Draw(new Rectangle(150, 275+(40 * iOption),32,20),
Selected, rcRect, DrawFlags.DoNotWait | DrawFlags.KeySource);
}
catch(SurfaceLostException)
{
RestoreSurfaces();
}
声音
声音最终总体上是一个非常简单的事情,但我在这方面遇到了一些问题。起初,DirectSound的示例似乎很简单,直到您注意到DirectSound使用的Device
类与DirectDraw使用的类同名。这意味着在创建这些变量时,我必须完整限定类名。
Microsoft.DirectX.DirectDraw.Device displayDevice;
Microsoft.DirectX.DirectSound.Device soundDevice;
为了创建SecondaryBuffer
对象来播放声音,我决定使用可执行文件中的流来将WAV文件加载到缓冲区中。为此,使用了GetManifestResourceStream
。我在这里遇到的问题是,资源必须完整限定程序集名称。
try
{
SkidBuffer = new SecondaryBuffer(
loadedAssembly.GetManifestResourceStream("Invasion.skid.wav"),
soundDevice);
}
catch(SoundException)
{
Console.WriteLine("load sounds error 1");
}
其余的转换
总的来说,剩余需要转换的部分都很顺利。我用ArrayList
类替换了链表。这在添加/删除UFO、子弹和其他物品时极大地简化了代码。您可以争辩说,使用STL的vector也能简化链表的处理,或者使用其他类型的容器类。我同意,这就是转换的原因。
将应用程序从C++转换为C#时,一个棘手的部分是记住这两种语言之间所有细微的差别。例如,在C++中,您可以使用rand()
生成随机数。对于C#,随机数是通过Random
类的实例生成的。这工作得很好,除了一个问题。我最初为每个UFO设置了它自己的随机变量。这原本没什么问题,直到我发现每个UFO都得到了相同的随机数。这是因为Random
的实例是用当前时间为变量播种的。这意味着单独的UFO变量会得到一个用相同时间播种的随机数生成器。每个随机数生成器都生成了完全相同的数字。一旦我将随机数生成器移到Invasion
类中,每个UFO就有了自己的值,事情就如预期一样运作了。
调试
调试全屏DirectX应用程序总是一件棘手的事情。对于这次转换,我使用了Console.Writeline
将数据打印到调试窗口。未处理的异常是遇到的大多数崩溃的根源;其中InvalidRectangleException
是最主要的问题。对于托管DirectX,使用try/catch
处理所有异常似乎非常重要。可以使用第二个显示器来简化事情,但在崩溃后在调试窗口中输出信息就足以解决问题了。历史
这个游戏的原版代码来自Mauricio Ritter的 Invasion - A computer game using DirectDraw。这是一个很棒的小游戏,拥有所有正确的图形和无限的游戏玩法。 Mauricio做得很好,所以我确保在他的署名中保留了他的名字。