- DebugDraw是Farseer物理引擎提供的一个功能,让我们还在开发阶段,能在屏幕上绘制对象数据,这将帮助您可视化body,fixtures ,以及其它物体。我在想,我们为什么不能在实际应用中使用相同的方法呢。而且我也没有找到任何足够的理由来不让自己这样做。因此,我弄了一个项目。名为“RenderXNA”
-这个项目包含三大类,RenderMaterial,Materials 和RenderXNAHelper。RenderMaterial类是我们在渲染对象时需要的数据结构。Materials类是辅助类,管理加载的纹理,所以不用担心一次又一次重复加载纹理。最后RenderXNAHelper类,这个类派生自FarseerPhysiscs.DebugView类和IDisposable接口。我们使用这个类来绘制,而不是写我们自己单独的代码。如果你仔细看代码,你会发现许多方法,比如DrawJoint,DrawShape,DrawPolygon,DrawCircle,DrawTexturedLine等,这些方法才真正绘制我们的对象。RenderXNAHelper使用World.BodyList得到所有可用于绘制的body。
在这里我不得不感谢一直支持我的卤面网版主,是他让我提起兴趣写了这么一篇文章,再次感谢卤面网,一个非常不错的wp7开发论坛,后面我也将再次向大家发布几篇高质量文章,请大家到卤面上找我吧,呵呵
进入正题:
- RenderXNAHelper源自Farseer物理引擎代码中DebugViewXNA.cs文件的DebugView。我改写了它,以便使用的项目以外的资源。 这样做能让我们的工作节省不少时间。
-OK。现在是使用的RenderXNA项目展示一个示例的时间了。在项目FarseerXNADemo1中,你可以找到RenderXNA.dll;我提供了所有的源代码,这些代码都会在最后一篇文章中提供下载。
- 我们还需要Camera2D类,我已经在一个例子中找到它的代码。它跑起来的确很像一个真的camera,我们不用仔细分析它的实现,直接就可以拿来用了(连我自己都不知道里面具体怎么实现的)。在Camera2D类中,几个非常有用的方法是ConvertScreenToWorld和ConvertWorldToScreen方法,这些方法转换屏幕点(实际点)到世界(系统)上的点,后面一个正好正反。我们也有矩阵类型的投影和视图属性,它们分别用来表示当前摄像头的投影和视角。这个类还包含需要在XNA Game类的Update方法调用的Update函数。以上是我们需要记住有关Camera2D类的相关知识。
- 现在我们开始做些简单的实现代码。继续增加一个新的Game2类,继承自Microsoft.Xna.Framework.Game类。它的构造和之前我们的项目Game1类是类似的。在Game2类也声明同一类级别的变量(和我们在Game1中一样)。除此之外,我们需要有更多Camera2D和RenderXNAHelper类型的变量。我们需要三个函数,即LoadContent,Update,Draw,所以先重载它们。在LoadContent中初始化Camera2D和RenderXNAHelper对象。首先复制Game1类中的所有LoadContent方法中的代码,并且在LoadContent创造对象世界后面添加下面的代码.
//Create DebugView and switch on the Flags to render shapes. RenderHelper = new RenderXNAHelper(MyWorld); RenderHelper.AppendFlags(DebugViewFlags.TexturedShape); RenderHelper.RemoveFlags(DebugViewFlags.Shape); RenderHelper.DefaultShapeColor = Color.White; RenderHelper.SleepingShapeColor = Color.LightGray; RenderHelper.LoadContent(GraphicsDevice, Content); Camera = new Camera2D(GraphicsDevice);
- 我们还需要给物理对象本身添加纹理细节,因为现在他们将要由RenderXNAHelper渲染。幸运的是,我们在FixtureFactory 的CreateRectangle方法中,有一个object类型的参数(几乎所有的工厂方法都有这么一方式,并将参数命名为UserData)。就像.NET控件的Tag属性一样。因此,当我们使用RenderMaterial对象时,我们可以指定它的质地,颜色等细节。例子代码如下。
new RenderMaterial(MyTexture, "Blank") { Color = Color.White }
-上面的代码将用白色对我们纹理进行遮罩(白色的地方,纹理将会绘制为原图像,而非白色部分,纹理将会被当前部分的颜色和图片的颜色进行遮罩合成的)
- 为floor,box的fixture中的FixtureFactory.CreateRectangle方法最后一个参数传入新RenderMaterial
protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); if (MyWorld != null) { // Update the camera Camera.Update(); // variable time step but never less then 30 Hz MyWorld.Step(Math.Min((float)gameTime.ElapsedGameTime.TotalMilliseconds * 0.001f, (1f / 30f))); RenderHelper.Update(gameTime); } base.Update(gameTime); } protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); if (MyWorld != null) { //Render the Data RenderHelper.RenderDebugData(ref Camera2D.Projection, ref Camera2D.View); } base.Draw(gameTime); }
-要运行这个新的游戏类,我们需要将项目属性设置为启动类型。
- 另外,我们需要添加字体和行的默认资源。
-你要注意的是,我们没有在Draw方法处理所有的绘制任务,相反,我们把部分绘制工作转移到RenderXNAHelper类。这将解决我们在屏幕上渲染对象的大部分的问题
本节总结,我们创建了物理对象,并能设置纹理,颜色和其他细节。FarseerXNADemo1的完整示例代码将在后面章节给出。
请大家关注下一节:
深入了解windowsphone7 游戏底层原理
我将在最后一节中放出所有源码与实例,毫无保留。
我希望你能喜欢我的文章!如果你有更多想法,请到卤面网 wp7开发论坛(codewp7.com)问答区联系我,我会很高兴知道你在想什么。同时wp7交流QQ群172765887中,也能找到我的身影,感谢大家