注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

风的驿站

一徐清风,半指烛光,觥筹已净,只余茶香。残卷一章,妙趣非常,忽闻帘响,愿闻其详?

 
 
 

日志

 
 
关于我

喜欢写生 编程 音乐 设计 喜欢把自己的想法变成实实在在的东西 喜欢安静的做一些事情 CSDN博客:http://blog.csdn.net/qwertyupoiuytr

网易考拉推荐

【原创】Box2D v2.3.0 用户指南(第十一章)  

2014-05-27 22:41:39|  分类: Box2D |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
【原创】Box2D v2.3.0 用户指南(第十一章) - 远行的风 - 风的驿站

第十一章 零碎资料(loose ends

11.1 用户数据(user data

b2Fixtureb2Body,以及b2Joint类允许你通过一个通用指针(void pointer)来附加一个用户数据,如果你需要检查Box2D的数据结构来看他们是怎样关联到游戏引擎中的对象的时候,会觉得用户数据非常方便。

例如,一种非常典型的用法是将一个角色(actor)的指针附加到它对应的刚体上(注:通过设置刚体的UserData属性),这建立了一个循环引用,如果你有角色对象,你可以获取它对应的物体对象,如果你有物体对象,你也可以获取它对应的角色对象。

GameActor* actor = GameCreateActor();

b2BodyDef bodyDef;

bodyDef.userData = actor;

actor->body = box2DWorld->CreateBody(&bodyDef);

下面是一些需要用到用户数据的具体例子:

· 通过碰撞结果对角色施加伤害

· 在玩家进入一个AABB中的时候调用一段脚本

· Box2D通知你一个关节要被析构掉的时候,获取一个游戏元素(结构)

注意你可以有选择的使用或者不使用用户数据,你可以用它存放任何东西。但是你前后需要保持一致。例如,如果你想要在物体上存储一个角色的指针,那么对于所有的物体,都需要将其对应的角色指针存储到用户数据中。千万不要在一个物体中存储角色指针,而在另一个物体中存储一个别的乱七八糟的(foo)指针,当将角色物体指针转强制换成其他的指针的时候,会导致异常发生。

用户数据指针默认指向NULL

对于装置,你可能想要定义一个用户数据结构用来存储游戏中特定的信息,例如材质类型,特效钩子(effect hooks),声音钩子(sound hooks)等等。

struct FixtureUserData

{

int materialIndex;

};

FixtureUserData myData = new FixtureUserData;

myData->materialIndex = 2;

b2FixtureDef fixtureDef;

fixtureDef.shape = &someShape;

fixtureDef.userData = myData;

b2Fixture* fixture = body->CreateFixture(&fixtureDef);

delete fixture->GetUserData();

fixture->SetUserData(NULL);

body->DestroyFixture(fixture);

 

11.2 隐式析构(implicit destruction

Box2D不使用引用计数(reference counting),所以如果你析构一个物体的话,那么它就真的不存在了。要访问一个已经释放了的物体指向的空间,会导致未知的问题。换句话说,你的程序很可能会崩溃。为了修复这些问题,在Debug编译模式下的内存管理器会将释放掉的内存区域填充上“FDFDFDFD”,这样在某些情况下,能使得查找问题原因变得更容易。

如果你析构了Box2D中的实体,你需要自己确保删掉所有指向被析构物体的引用,如果你只有一个实体的引用,那么很容易这样做,但是如果你有很多引用的话,那么你就应该考虑实现一个句柄类(handle class)来封装一下原始指针(raw pointer)。

通常在Box2D中你会构造和析构很多物体、形状和关节。这些实体在某种意义上说都是由Box2D来管理的,如果你析构一个物体的话,那么所有相关的形状和关节都自动析构掉了,这就是标题中所谓的隐式析构。

当你析构一个物体的时候,所有附加到它上面的形状,关节和接触都被析构掉了,这就叫做隐式析构。(这个地方不知道为什么又要来一遍,原文中就是这么说的)所有连接到这些析构掉的关节或者接触的物体都被唤醒(woken)了。这种处理方式通常很方便,但是你要留意一个严重的问题:你需要将指向这些析构掉的形状和关节的指针置为NULL,否则,当你的程序后面尝试访问或者析构这些对象的时候,它会死的很惨(die horribly)。

为了帮助你将关节指针置为NULLBox2D提供了一个叫b2DestructionListener的监听类,你可以实现这个类,然后将这个类传递给世界对象。接着世界对象就会在有关节被隐式析构的时候通知你的实现类。

需要注意的是,当某个关节或者装置被显示析构掉的时候,是没有通知的,这种情况下所有关系非常明确,你可以立即进行必要的清理工作。如果你愿意的话,你可以调用你自己实现的b2DestructionListener类中的清理方法,以保持方法的统一性。

隐式析构在很多情况下非常方便,但是同时它也可能让你的程序崩溃。你可能在你的代码中某处存储指向形状、关节等实体的指针,当指向的物体被析构的时候,这些指针也就失效了,更糟糕的情况是:你想一下,关节的创建代码通常和与它相关联的物体的管理代码无关,例如,testbed为了模拟和屏幕物体的交互而创建的b2MouseJoint类型的关节。

当隐式析构发生时,Box2D提供了一个回调机制来通知你的应用。这给你的程序提供了一个机会来将那些无效指针置为NULL,这个回调机制会在后面做描述。

你可以实现一个b2DestructionListener类,允许b2World来通知你某个形状或者关节被隐式析构了(由于相关的物体被析构了),这可以避免你的代码访问野指针。

class MyDestructionListener: public b2DestructionListener

{

void SayGoodbye(b2Joint* joint)

{

    // remove all references to joint

}

};

然后你需要将你的析构监听器(destruction listener)的实例注册到世界中,在世界对象的初始化方法中使用下面的语句进行注册:

myWorld->SetListener(myDestructionListener);

 

11.3 像素和坐标系(pixels and coordinate systems

回忆一下我们讲过的,Box2D使用MKS(米,千克,秒)单位制以及弧度制,在使用米为单位的时候,你可能会遇到麻烦,因为你的游戏是用像素来作为单位的。在testbed中我们有一个游戏完全使用米作为单位,仅仅需要使用OpenGL提供的视图变换(viewport transformation)来将世界坐标转换为屏幕坐标系下的尺寸。

float lowerX = -25.0f, upperX = 25.0f, lowerY = -5.0f, upperY = 25.0f;

gluOrtho2D(lowerX, upperX, lowerY, upperY);

如果你的游戏必须要再像素单位制下才能工作,那么当你从Box2D重传出参数时,需要将长度单位从米转换为像素。当你需要向Box2D中传入参数时,需要将长度单位从像素转换为米。这样能够提高物理模拟的稳定性。

你需要一个合理的转换因子(conversion factor),我建议根据你的角色大小来做一个合理的选择。假设你决定使用50像素来代表1米(因为你的角色可能是75像素高),那么你可以通过下面的方程来进行转换:

xMeters = 0.02f * xPixels;

yMeters = 0.02f * yPixels;

反过来:

xPixels = 50.0f * xMeters;

yPixels = 50.0f * yMeters;

你应该考虑在你的游戏代码中使用MKS单位制,仅仅在渲染的时候使用像素。这样可以简化你的游戏逻辑,减少犯错的机会,因为在渲染时做变换可以被隔离为一小段代码。

如果你使用转换因子,你应该尝试去修改它,以保证不会出现异常。你也可以尝试去调整它来提高稳定性。


Box2D v2.3.0 用户指南(第十二章)

  评论这张
 
阅读(311)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017