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

news/2024/7/20 21:25:30 标签: IOS, box2d, 用户指南



第七章装置(fixture)

7.1简介

回想一下,我们曾经说过形状并不知道它依附于的物体的存在,它们能够在物理模拟中独立使用。因此Box2D提供了b2Fixture类来讲形状附加到物体上。一个物体可以没有装置,也可以由多个装置,一个有一个以上装置的物体通常称为一个组合体(compoundbody)。

装置有以下组成元素:

·一个单独的形状

·broad-phase代理(可以有多个)

·密度(density),摩擦力(friction)和弹力(restitution

·碰撞过滤标记(collision filtering flags

·指回父物体的指针

·用户数据(user data

·传感器标记(sensor flag

 

7.2创建装置

要创建一个装置,首先需要初始化一个装置定义(fixturedefinition),然后将装置定义作为参数传给父物体的方法:

b2FxitureDeffixtureDef;

fixtureDef.shape= &myShape;

fixtureDef.density= 1.0f;

b2Fixture*myFixture = myBody->CreateFixture(&fixtureDef);

这段代码创建好一个装置,并且将这个装置附加到物体上。你不需要去保存这个装置的指针,因为当父物体被析构的时候,这个附加到物体上的装置也会被自动析构。你可以创建多个装置附加到物体上。

你可能需要析构一个物体上的装置,以此来模拟一个可分裂的对象,否则的话,你不需要去管它们,让物体的析构函数来替你处理掉附加的装置就可以了。

myBody->DestoryFixture(myFixture);

 

密度

装置的密度是用来计算父物体的质量的,密度可以是0甚至是负数,你应该为所有的装置使用相似的密度,这样做可以提高堆叠的稳定性。

当你设置密度时,物体的质量并不会随之发生改变,你必须要手动调用ResetMassData方法来重新计算物体的质量。

fixture->SetDensity(5.0f);

body->ResetMassData();

 

摩擦力

摩擦力用来让物体更真实的沿着其他对象滑动,Box2D支持静摩擦力(staticfriction)和动摩擦力(dynamicfriction),但是二者使用同一个属性值进行设置。摩擦力在Box2D中能够被精确模拟,摩擦力的大小等于接触面的压力(normalforce)乘以摩擦系数,这种称为Coulombfriction(库伦摩擦)。摩擦系数通常在0到1之间,但是任何非负数都是有效的。当摩擦系数为0时,物体表面没有摩擦力,当摩擦系数为1时,物体表面会具有很大的摩擦力。在计算两个形状之间的摩擦力时,Box2D会结合两个形状的父装置的摩擦系数,通过计算他们的几何平均值得出:

float32friction;

friction= sqrtf(fixtureA->friction * fixtureB->friction);

因此当其中一个装置具有大小为0的摩擦系数时,整个接触面上就不会有摩擦力存在(摩擦力为0)。

你可以重写b2Contact::SetFriction方法来使用不同的计算方程,这通常实在b2ContactListener的回调函数中完成的。

 

弹性

物体的弹性用来使物体在接触后反弹。弹性系数通常在0到1之间。我们考虑下面的情形:将一个小球坠落在一张桌子上,当弹性系数为0时,小球完全不会弹起(直接就砸到桌子上不动了),这种情况称为(完全)非弹性碰撞;当弹性系数为1时,小球会以完全相同的速度向上弹起(这意味着小球会达到坠落的初始高度,没有能量损失),这称为完全弹性碰撞。两个物体间的弹性系数通过下面的方程来计算:

float32restitution;

restitution= b2Max(fixtureA->restitution, fixtureB->restitution);

弹性系数通过这样的方式来计算,这样你就可以有一个非常有弹力的小球,而不需要有一个非常有弹力的地面了。(注:因为是取二者的较大值,所以小球具有弹力就可以解决问题了)

你可以重写b2Contact::SetRestitution方法来使用不同的计算方程,这通常实在b2ContactListener的回调函数中完成的。

当一个形状执行多次碰撞时,弹性会被近似的模拟,这是由于Box2D使用迭代解析器的缘故。当碰撞的入射速度非常小的时候,Box2D会使用(完全)非弹性碰撞进行模拟,这是为了防止抖动。入射速度的阈值请参考定义在b2Settings.h文件中的b2_velocityThreshold常量。

 

过滤(filtering)

碰撞过滤允许你避免装置间的碰撞。例如:假设你有一个骑自行车的角色,你希望自行车和地形发生碰撞,角色也和地形发生碰撞,但是你不希望你的角色和自行车发生碰撞(因为显然他们彼此重叠),这时你就需要设置过滤标记。Box2D中通过分类(category)和组(group)来支持这种碰撞过滤。

Box2D支持16种碰撞分类,对于每一个装置,你都可以指定它属于某一个碰撞分类,同时你可以指定那些碰撞分类可以与当前装置发生碰撞。举例来说,在一个多人游戏中,你可以指定所有的玩家彼此之间不发生碰撞,所有的怪兽彼此间不发生碰撞,但是玩家和怪兽之间可以发生碰撞。通过指定蒙版标记(masking bits),例如:

playerFixtureDef.filter.categoryBits= 0x0002;

monsterFixtureDef.filter.categoryBits= 0x0004;

playerFixtureDef.filter.maskBits= 0x0004;

monsterFixtureDef.filter.maskBits= 0x0002;

下面是当碰撞能够发生时的判断条件:

uint16catA = fixtureA.filter.categoryBits;

uint16maskA = fixtureA.filter.maskBits;

uint16catB = fixtureB.filter.categoryBits;

uint16maskB = fixtureB.filter.maskBits;

if((catA & maskB) != 0 && (catB & maskA) != 0)

{

// fixtures can collide

}

碰撞组(collisiongroup)允许你指定一个整数的组索引值,你可以设置具有相同组索引值的装置发生碰撞(正索引),也可以设置所有具有相同组索引值的装置不会彼此碰撞(负索引),组索引值通常用于以某种方式相关联的物体之间,比如自行车的部件。在下面的例子中,fixture1和fixture2会发生碰撞,fixture3和fixture4不发生碰撞:

fixture1Def.filter.groupIndex= 2;

fixture2Def.filter.groupIndex= 2;

fixture3Def.filter.groupIndex= -8;

fixture4Def.filter.groupIndex= -8;

具有不同组索引值的装置在发生接触的时候,通过categoryBits和maskBits来判断是否发生碰撞,也就是说,组索引值相比于蒙版标记具有更高的优先级(higherprecedence)。

注意,除了上述过滤规则,Box2D中还有下面的过滤规则:

·静态物体(static)上的装置只能和动态物体发生碰撞

·运动物体(kinematic)上的装置只能和动态物体发生碰撞

·同一个物体上的装置之间不会发生碰撞

·你可以选择“启用/禁用“关节绑定的物体上面的装置的碰撞

有时候你需要为已经创建出来的装置指定碰撞过滤条件,你可以通过调用b2Fixture::GetFilterData和b2Fixture::SetFilterData方法来获取(get)和设置(set)装置的b2Filter结构。需要注意的一点是,修改过滤条件不会在当前时间间隔(timestep)生效,下一个时间间隔才会起作用(参考世界类)。

 

7.3传感器(sensor

有时候游戏逻辑需要知道两个装置重叠在了一起,尽管此时没有发生任何碰撞,这可以通过传感器来实现。传感器是一种能够察觉到碰撞的装置,但是传感器不会响应这个碰撞。

你可以将任何一个装置标记为传感器,传感器可以使静态的(static),运动的(kinematic),或者动态的(dynamic),我们知道一个物体上可以附加多个装置,所以在物体上传感器和真正的装置(非传感器)可以混合存在。此外,当接触的两个物体之中至少有一个动态物体时,传感器才会感知到物体彼此接触,所以传感器无法够捕获这几种物体之间的接触:运动物体-运动物体,运动物体-静态物体,静态物体-静态物体。

传感器不会生成接触点,有两种方法可以得到传感器的状态:

1.   b2Contact::IsTouching

2.   b2ContactListener::BeginContactand EndContact



http://www.niftyadmin.cn/n/878350.html

相关文章

mysql注入 检查函数_MySQLStudy——SQL注入 事务 视图 函数 触发器

SQL注入登录验证时的SQL注入攻击写sql语句的时候, %传值的时候, 需要加引号:sql "select * from t4 where name %s and pwd %s" % (username, pwd)上面的sql语句带来的风险是:例一:username zekai#select * from t4 where name zekai# and pwd 例二:username dbs…

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

第八章 关节(joint) 8.1简介 关节用来将物体约束到世界(world),或者约束到其他物体上。在游戏中比较典型的例子有木偶,跷跷板和滑轮等等。可以由很多种不同的方式构成关节来生成…

mysql内存分页是什么意思_详解数据库中的分页、内存和I/O延迟

几年前我写了一篇关于 AIX 调优的文章,现在 AIX 7 出现了,所以有必要重新审视需要在 AIX 系统上执行的基本调优措施。已经发布的许多技术级别 (TL) 和一些建议可能会改变。在本文中,我将提供与 AIX 5.3、6.1 和 7 中的可调项相关的 AIX 调优信…

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

第九章 接触(contact) 9.1简介 接触是Box2D创建的用来管理装置间的碰撞的物体。如果装置具有子物体(child),例如链形状(chainshape),那么每一个相关的子物…

python如何升级numpy_python – 如何升级numpy?

当我使用brew安装OpenCV时,每当我运行这个命令来测试python -c“import cv2”时,我得到这个问题RuntimeError: module compiled against API version 9 but this version of numpy is 6Traceback (most recent call last):File "", line 1, in…

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

第十章 世界类(world class) 简介 b2World类包含物体(body)和关节(joint),它负责模拟工作的各个方面并且支持异步的查询(例如AABB查询和射线投射等等&…

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

第十一章零碎资料(loose ends) 11.1用户数据(user data) b2Fixture,b2Body,以及b2Joint类允许你通过一个通用指针(void pointer)来附加一个用户数据&…

微信小程序swiper图片尺寸_微信小程序 swiper 轮播图 高度自适应

微信小程序 swiper 轮播图 高度自适应发布时间:2018-07-20 15:34,浏览次数:588, 标签:swiper小程序中使用swiper 组件 ,实现轮播图高度自适应效果。先上最终实现效果图先看一下微信官方文档介绍 swiper 组件https://developers.w…