import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.EdgeShape;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.joints.PrismaticJointDef;
public class CollisionFiltering extends Box2DTest {
private final static short k_smallGroup = 1;
private final static short k_largeGroup = -1;
private final static short k_defaultCategory = 0x01;// 二进制1 short的话就是:0000 0001
private final static short k_triangleCategory = 0x02;// 二进制10
private final static short k_boxCategory = 0x04;// 二进制100
private final static short k_circleCategory = 0x08;// 二进制1000
/**
* 在计算机中,负数以其正值的补码形式表达,方法为其绝对值求反加一。
例如 -100的绝对值为100
100原码:1000 0000 0110 0100
100反码:1111 1111 1001 1011
100补码:1111 1111 1001 1100=1111 1111 1001 1011(反码) +1
所以-100二进制表示为:1111 1111 1001 1100
原码:一个整数按绝对值大小转换成的二进制数称为原码;
反码:将二进制数按位取反,所得的新二进制数称为原二进制数的反码;(取反操作:1变0,0变1)
补码:反码加1称为补码。
判断是否碰撞的源码:
bool b2ContactFilter::ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB)
{
const b2Filter& filterA = fixtureA->GetFilterData();
const b2Filter& filterB = fixtureB->GetFilterData();
if (filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0)
{
return filterA.groupIndex > 0;
}
bool collide = (filterA.maskBits & filterB.categoryBits) != 0 &&
(filterA.categoryBits & filterB.maskBits) != 0;// 同时满足两个条件才发生碰撞
return collide;
}
位与运算符(&)
运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。
比如:129&128.
129转换成二进制就是10000001,128转换成二进制就是10000000。从高位开始比较得到,得到10000000,即128.
(filterA.maskBits & filterB.categoryBits) != 0
如category 0010 mask 1101 那么就是零,这个mask相当于category第二位的都不相撞?
下面的-1意思是不过滤?
*/
private final static short k_triangleMask = -1;// short-1二进制表示就是:1111 1111
// ^异或运算,相同值0不同值1 那么1111 1111 1111 1111 ^ 0000 0000 0000 0010 就变成 1111 1111 1111 1101
// 1111 1111 1111 1101 > 反补位? 1111 1111 1111 1100 > 反转 0000 0000 0000 0011 > 3 所以是-3。
// 这里意思是category为0010的都不碰撞,意思是和三角形都不发生碰撞?
private final static short k_boxMask = -1 ^ k_triangleCategory;
// 二进制 1111 1111
private final static short k_circleMask = -1;
@Override
protected void createWorld (World world) {
{
EdgeShape shape = new EdgeShape();
shape.set(new Vector2(-40.0f, 0), new Vector2(40, 0));
FixtureDef fd = new FixtureDef();
fd.shape = shape;
fd.friction = 0.3f;
BodyDef bd = new BodyDef();
Body ground = world.createBody(bd);
ground.createFixture(fd);
shape.dispose();
}
Vector2[] vertices = new Vector2[3];
vertices[0] = new Vector2(-1, 0);
vertices[1] = new Vector2(1, 0);
vertices[2] = new Vector2(0, 2);
PolygonShape polygon = new PolygonShape();
polygon.set(vertices);// 三角形?
FixtureDef triangleShapeDef = new FixtureDef();
triangleShapeDef.shape = polygon;
triangleShapeDef.density = 1.0f;
// 小物体组,小物体组的成员如果是负数组都不发生碰撞,正数反之
// 优先级比后面两个高
// 0000 0000 0000 0001
triangleShapeDef.filter.groupIndex = k_smallGroup;
// 类型:16种类型(short),只有同种类型可以碰撞?
// 二进制:0000 0000 0000 0010
triangleShapeDef.filter.categoryBits = k_triangleCategory;
// 二进制:1111 1111 1111 1111
// triangleMask不过滤,放行mask
triangleShapeDef.filter.maskBits = k_triangleMask;
BodyDef triangleBodyDef = new BodyDef();
triangleBodyDef.type = BodyType.DynamicBody;
triangleBodyDef.position.set(-5, 2);
Body body1 = world.createBody(triangleBodyDef);
body1.createFixture(triangleShapeDef);
short SCALE = 4;
/* vertices[0].scl(2);
vertices[1].scl(2);
vertices[2].scl(2);*/
vertices[0].scl(SCALE);
vertices[1].scl(SCALE);
vertices[2].scl(SCALE);
polygon.set(vertices);// 第二次就不用定义triangleShapeDef.shape了?
triangleShapeDef.filter.groupIndex = k_largeGroup;
triangleBodyDef.position.set(-5*SCALE, 6);
triangleBodyDef.fixedRotation = true;
Body body2 = world.createBody(triangleBodyDef);
body2.createFixture(triangleShapeDef);
{
BodyDef bd = new BodyDef();
bd.type = BodyType.DynamicBody;
bd.position.set(-5, 10);
Body body = world.createBody(bd);
PolygonShape p = new PolygonShape();
p.setAsBox(0.5f, 1.0f);
body.createFixture(p, 1);
PrismaticJointDef jd = new PrismaticJointDef();
jd.bodyA = body2;// 大三角形
jd.bodyB = body;
/* jd.enableLimit = true;
jd.localAnchorA.set(0, 4);
jd.localAnchorB.set(0, 0);
jd.localAxisA.set(0, 1);
jd.lowerTranslation = -1;
jd.upperTranslation = 1;*/
jd.enableLimit = true;// 可以无限制上下伸缩
jd.localAnchorA.set(0, 4);
// B比A的y大那么小长方形就到下面去了?
// 上面是轴1,这个是轴2,分别可以两段轴,然后下面那个距离设了就是轴2可以偏离轴1的距离和方向?
// 反正这个anchor和那个是反的
jd.localAnchorB.set(0, -2);
jd.localAxisA.set(2, 2);// 这个不知道什么意思,(100,0)就是可以横移?(2,2)意思是可以斜移?
jd.lowerTranslation = 0;
jd.upperTranslation = 1;// 这两个是可以滑动的距离
world.createJoint(jd);
p.dispose();
}
polygon.setAsBox(1, 0.5f);
FixtureDef boxShapeDef = new FixtureDef();
boxShapeDef.shape = polygon;
boxShapeDef.density = 1;
//boxShapeDef.restitution = 0.1f;// 如落地以后反弹高度?
boxShapeDef.restitution = 0.1f;
boxShapeDef.filter.groupIndex = k_smallGroup;// smallGroup都可以互相碰撞
boxShapeDef.filter.categoryBits = k_boxCategory; // 只能和矩形撞?
// 这个mask意思是不能和三角形碰撞(过滤三角形的mask),
// 但是由于是k_smallGroup,这个group优先,所以可以和小三角形碰撞。
boxShapeDef.filter.maskBits = k_boxMask;
BodyDef boxBodyDef = new BodyDef();
boxBodyDef.type = BodyType.DynamicBody;
boxBodyDef.position.set(0, 2);
Body body3 = world.createBody(boxBodyDef);
body3.createFixture(boxShapeDef);
//polygon.setAsBox(2, 1);
polygon.setAsBox(4, 2);
boxShapeDef.filter.groupIndex = k_largeGroup; // largeGroup都不可以互相碰撞
boxBodyDef.position.set(0, 6);
Body body4 = world.createBody(boxBodyDef);
body4.createFixture(boxShapeDef);
CircleShape circle = new CircleShape();
circle.setRadius(1);
FixtureDef circleShapeDef = new FixtureDef();
circleShapeDef.shape = circle;
circleShapeDef.density = 1.0f;
circleShapeDef.filter.groupIndex = k_smallGroup;
circleShapeDef.filter.categoryBits = k_circleCategory;
// circleMask不过滤,放行mask
circleShapeDef.filter.maskBits = k_circleMask;
BodyDef circleBodyDef = new BodyDef();
circleBodyDef.type = BodyType.DynamicBody;
circleBodyDef.position.set(5, 2);
Body body5 = world.createBody(circleBodyDef);
body5.createFixture(circleShapeDef);
circle.setRadius(4);
circleShapeDef.filter.groupIndex = k_largeGroup;
circleBodyDef.position.set(5, 6);
Body body6 = world.createBody(circleBodyDef);
body6.createFixture(circleShapeDef);
}
}
[LIBGDX学习]LibGDX代码详解(八)Box2D collision filtering
最新推荐文章于 2018-03-01 16:47:42 发布