[LIBGDX学习]LibGDX代码详解(八)Box2D collision filtering

 
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);
	}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值