WP7平衡球游戏开发教程(三)--DebugDraw(XNA渲染)

- 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中,也能找到我的身影,感谢大家


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Cocos2d-x 3.7 版本中,碰撞检测是通过物理引擎来实现的。你可以使用 Box2D 或 Chipmunk 物理引擎来处理碰撞。 首先,你需要在场景中创建物理世界,并将物理引擎设置为 Box2D 或 Chipmunk。例如,使用 Box2D 物理引擎: ```cpp auto scene = Scene::createWithPhysics(); scene->getPhysicsWorld()->setDebugDrawMask(PhysicsWorld::DEBUGDRAW_ALL); this->addChild(scene); ``` 然后,你可以为需要进行碰撞检测的节点添加物理组件。例如,创建一个精灵并为其添加物理组件: ```cpp auto sprite = Sprite::create("sprite.png"); auto body = PhysicsBody::createCircle(sprite->getContentSize().width / 2); sprite->setPhysicsBody(body); ``` 接下来,你可以设置碰撞回调函数来处理碰撞事件。例如,创建一个碰撞监听器并设置碰撞回调函数: ```cpp auto contactListener = EventListenerPhysicsContact::create(); contactListener->onContactBegin = [](PhysicsContact& contact) { // 处理碰撞开始事件 return true; // 返回 true 表示继续处理碰撞事件,返回 false 表示忽略该碰撞事件 }; Director::getInstance()->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this); ``` 在碰撞开始事件的回调函数中,你可以根据需要处理碰撞事件,例如改变精灵的位置、播放动画等。 这是一个简单的示例,你可以根据自己的需求进行更复杂的碰撞检测和处理。记得在处理碰撞事件时,要根据具体情况进行适当的优化,避免性能问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值