Box2D(2.1a)引擎的群组筛选碰撞详解

关于box2d的群组筛选功能是怎么回事一直有点不明所以,现在经过一系列实验,终于明白box2d群组筛选的控制机制了。群组碰撞筛选的核心属性有2个,分别是b2FilterData的categoryBits属性以及maskBits属性;(b2FilterData作为b2FixtureDef的filter对象存在)categoryBits是刚体的所属群组id值域为0x0000-0xFFFF;而maskBits属性则是当前刚体接受碰撞的"掩码";测试结果显示,两个物体是否碰撞,受到两个条件的制约。分为3个步骤;这里举例刚体A和刚体B;
1:会对A的掩码和B的群组ID进行按位或运算,得到结果a1(这里简化为true/false);
2:对B的掩码和A的群组ID进行按位或运算,得到b1(true/false);
3:决定碰撞,对a1和b1进行与运算;得到结果为true则两物体进行碰撞;否则穿过;
所以,默认情况下所有的b2FilterData的maskBits属性为0xFFFF——与所有物体碰撞;
例如下面测试代码
矩形物体会从中间开始下落到静态体圆形上;从而观察碰撞效果;

import Box2D.Collision.Shapes.b2CircleShape;
import Box2D.Collision.Shapes.b2PolygonShape;
import Box2D.Dynamics.b2World;
import Box2D.Dynamics.b2Body;
import Box2D.Common.Math.b2Vec2;
import Box2D.Dynamics.b2Fixture;
import Box2D.Dynamics.b2FixtureDef;
import Box2D.Dynamics.b2BodyDef;
import Box2D.Dynamics.b2DebugDraw;
 
var world:b2World=new b2World(new b2Vec2(0,2),true);
var b2d:b2BodyDef=new b2BodyDef();
b2d.position.Set(200/30,100/30);
b2d.type=b2Body.b2_dynamicBody;
var bb:b2Body=world.CreateBody(b2d);
var fx:b2FixtureDef=new b2FixtureDef();
fx.friction=1;
fx.restitution=0.1;
fx.shape=b2PolygonShape.AsBox(400/30,7.5/30);
fx.density=1;
fx.filter.categoryBits=0x1100;//方形体群ID
fx.filter.maskBits=0x1101;//方形体掩码(对于碰撞对方的)因为是按位或运算所以每位的数字就不重要了;(过滤群ID为0x00X0)的ID
bb.CreateFixture(fx);
//完成方形创建 
fx.shape=new b2CircleShape(100/30);
fx.filter.categoryBits=0x0011;//圆形体群ID
fx.filter.maskBits=0x0111;//圆形体掩码(过滤群ID为0xX000)的群
//通过两轮过滤之后还要将结果进行与运算,得出最终是否可碰撞;
b2d.position.Set(400/30,300/30);
b2d.type=b2Body.b2_staticBody;
bb=world.CreateBody(b2d);
bb.CreateFixture(fx);
//完成圆形创建
var sp:Sprite=new Sprite();
addChild(sp);
var dbg:b2DebugDraw=new b2DebugDraw();
dbg.SetSprite(sp);
dbg.SetFlags(b2DebugDraw.e_shapeBit);
dbg.SetDrawScale(30);
dbg.SetLineThickness(0);
dbg.SetFillAlpha(0.5);
world.SetDebugDraw(dbg);
addEventListener(Event.ENTER_FRAME,run);
function run(e:Event){
	world.Step(1/30,10,10);
	world.ClearForces();
	world.DrawDebugData();
}

你可能感兴趣的:(学习笔记)