Jbox2.2学习

 * 以下为学习笔记 * @author 十

关于filter

Box2D supports 16 collision categories. For each fixture you can specify which category it belongs to. You also specify what other categories this fixture can collide with. For example, you could specify in a multiplayer game that all players don't collide with each other and monsters don't collide with each other, but players and monsters should collide. This is done with masking bits. For example:

body1.getFixtureList().m_filter.groupIndex=1;
body1.getFixtureList().m_filter.maskBits=2;
body1.getFixtureList().m_filter.categoryBits=2;

Here is therule for a collision to occur:

int catA = fixtureA.m_filter.categoryBits;
int maskA = fixtureA.m_filter.maskBits;
int catB = fixtureB.m_filter.categoryBits;
int maskB = fixtureB.m_filter.maskBits; 

if ((catA & maskB) != 0 && (catB & maskA) != 0)
{
  // fixtures can collide
}

Collision groups let you specify an integral group index. You can have all fixtures with the same group indexalways collide (positive index) ornever collide (negative index). Group indices are usually used for things that are somehow related, like the parts of a bicycle. In the following example, fixture1 and fixture2 always collide, but fixture3 and fixture4 never collide.

fixture1Def.m_filter.groupIndex = 2;
fixture2Def.m_filter.groupIndex = 2;
fixture3Def.m_filter.groupIndex = -8;
fixture4Def.m_filter.groupIndex = -8;

Collisions between fixtures of different group indices are filtered according the category and mask bits. In other words, g roup filtering has higher precedence than category filtering.

Note that additional collision filtering occurs in Box2D. Here is a list:

·         A fixture on a static body can only collide with a dynamic body.

·         A fixture on a kinematic body can only collide with a dynamic body.

·         Fixtures on the same body never collide with each other.

·         You can optionally enable/disable collision between fixtures on bodies connected by a joint.

Sometimes you might need to change collision filtering after a fixture has already been created. Note that changing the filter data willnotadd or remove contacts until the next time step (see the World class).


v_iterations与p_iterations

In addition to the integrator, Box2D also uses a larger bit of code called a constraint solver. The constraint solver solves all the constraints in the simulation, one at a time. A single constraint can be solved perfectly. However, when we solve one constraint, we slightly disrupt other constraints. To get a good solution, we need to iterate over all constraints a number of times.

There are two phases in the constraint solver: a velocity phase and a position phase. In the velocity phase the solver computes the impulses necessary for the bodies to move correctly. In the position phase the solver adjusts the positions of the bodies to reduce overlap and joint detachment. Each phase has its own iteration count. In addition, the position phase may exit iterations early if the errors are small.

The suggested iteration count for Box2D is 8 for velocity and 3 for position. You can tune this number to your liking, just keep in mind that this has a trade-off between speed and accuracy. Using fewer iterations increases performance but accuracy suffers. Likewise, using more iterations decreases performance but improves the quality of your simulation


旋转关节

	public RevoluteJoint createRevoluteJoint() {
		//创建一个旋转关节的数据实例 
		RevoluteJointDef rjd = new RevoluteJointDef();
		//初始化旋转关节数据
		rjd.initialize(body1, body2, body1.getWorldCenter());
		rjd.maxMotorTorque = 1;// 马达的预期最大扭矩
		rjd.motorSpeed =20;//马达最终扭矩
		rjd.enableMotor = true;// 启动马达
		//利用world创建一个旋转关节
		RevoluteJoint rj = (RevoluteJoint)world.createJoint(rjd);
		return rj ;
	}
* 马达预期最大扭矩:Body在进行旋转运动开始的一个扭矩值可以简单理解为旋转速度。
* 马达最终扭矩:马达最终会以一个固定的转速来运动,而这个速度取决于最终扭矩


如果要限制旋转的角度,可以加上

rjd.enableLimit=true;
rjd.lowerAngle=1;
rjd.upperAngle=-1;

如果要设置所连接的两个刚体的锚点偏移,将initialize方法拆分设置参数

rjd.bodyA=body1;
		rjd.bodyB=body2;
		rjd.localAnchorA=new Vec2(body1w/4/RATE, 0);
		rjd.localAnchorB=new Vec2(0, -body2h/4/RATE);
这里的localAnchor分别表示A,B的局部锚点坐标( 注意,这里锚点不能设置到刚体外部,否则无效= =忘记加乘RATE=30这个系数导致这个问题真是弱智爆的隐蔽)

齿轮关节

	// 齿轮关节
	public GearJoint createGearJoint() {
		//创建齿轮关节数据实例
		GearJointDef gjd = new GearJointDef();
		//设置齿轮关节的两个Body
		gjd.bodyA = body1;
		gjd.bodyB = body2;
		//设置齿轮关节绑定的两个旋转关节
		gjd.joint1 = rj1;
		gjd.joint2 = rj2;
		//设置旋转角度比
		gjd.ratio = 10;
		//通过world创建一个齿轮关节
		GearJoint gj = (GearJoint) world.createJoint(gjd);
		return gj;
	}

* ratio: 表示【自运动的旋转关节】转动十周时,【被带动的旋转关节】正好转动一周


滑轮关节

两个body谁上谁下完全取决于它们的质量大小

	// 滑轮关节(让物体沿着 一个世界锚点进行滑轮)

	public PulleyJoint createPulleyJointDef() {
		//创建滑轮关节数据实例
		PulleyJointDef pjd = new PulleyJointDef();
		Vec2 ga1 = new Vec2(anchor1x/ RATE,anchor1y/ RATE);
		Vec2 ga2 = new Vec2(anchor2x/ RATE,anchor2y/ RATE); 
		//初始化滑轮关节数据
		//body,两个滑轮的锚点,两个body的锚点,比例系数
		pjd.initialize(body1, body2, ga1, ga2, body1.getWorldCenter(), body2
				.getWorldCenter(), 1f);
		PulleyJoint pj = (PulleyJoint) world.createJoint(pjd);
		return pj;
	}
这里的比例系数raito即 轻的那个上升h,重的那个下降h*raito

若ratio=1,当length1=5时,length2=21;

若ratio=2,当length1=5时,length2=26;

若ratio=3,当length1=5时,length2=31;


移动关节

public PrismaticJoint createPrismaticJoint() {
		//创建移动关节数据实例
		PrismaticJointDef pjd = new PrismaticJointDef();
		//预设马达的最大力
		pjd.maxMotorForce = 10;
		//马达的最终力
		pjd.motorSpeed = 10;
		//启动马达
		pjd.enableMotor = true;
		//设置位移最小偏移值
		pjd.lowerTranslation = -3.0f / RATE;
		//设置位移最大偏移值
		pjd.upperTranslation = 3.0f / RATE;
		//启动限制
		pjd.enableLimit = true;
		//初始化移动关节数据
		pjd.initialize(body1, body2, body1.getWorldCenter(), new Vec2(0, 1));
		//通过world创建一个移动关节
		PrismaticJoint pj = (PrismaticJoint) world.createJoint(pjd);
		return pj;
	}

* 移动关节中【预设马达的最大力】无效,默认从0缓动

* 绑定在移动关节上的Body在移动过程不会发生角度的偏移


		//设置位移最小偏移值
		pjd.lowerTranslation = -3.0f / RATE;
		//设置位移最大偏移值
		pjd.upperTranslation = 3.0f / RATE;
		//启动限制
		pjd.enableLimit = true;
如果不写这几句话则相对距离与位置会偏移

关于Sensor

将刚体设为Sensor会导致碰撞可检测但无反应的状态

	lostBody1.getFixtureList().m_isSensor=true;
	lostBody2.getFixtureList().setSensor(true);
以上两种写法均可(=A=吐槽:既然有 setSensor(boolean sensor)isSensor()了干嘛还开放m_isSensor!封装性好差)

另外需注意

Sometimes game logic needs to know when two fixtures overlap yet there should be  no collision response. This is done by using sensors. A sensor is a fixture that  detects collision but does not produce a response.
 You can flag any fixture as being a sensor. Sensors may be static or dynamic. 
 Remember that you may have multiple fixtures per body and you can have any mix of sensors and solid fixtures.Sensors do not generate contact points. There are two ways to get the state of a sensor:
  1.       b2Contact::IsTouching
  2.       b2ContactListener::BeginContact andEndContact
即不能将涉及sensor的碰撞检测写到ContactListenerpreSolvepostSolve方法里,否则死活检测不到的


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值