您的当前位置:首页正文

Box2D的EdgeShape的碰撞处理

2020-11-09 来源:爱站旅游

有时候两个body碰撞时需要精确到某条边,所以在创建body的时候需要创建multiFixture,也就是多个fixture的组合。早期Box2D版本中Polygon Shape有setAsEdge方法设置每条边的fixture,v2.2.1之后只有setAsBox方法了。 方法一:可以在每条边的位置上加上一个Edg

有时候两个body碰撞时需要精确到某条边,所以在创建body的时候需要创建multiFixture,也就是多个fixture的组合。早期Box2D版本中Polygon Shape有setAsEdge方法设置每条边的fixture,v2.2.1之后只有setAsBox方法了。

方法一:可以在每条边的位置上加上一个Edge Shape,然后再body中加入这个边的fixture并保存起来,碰撞的时候就能判断是碰到哪条边了。

方法二:直接用body的createFixture(edgeShape,density)方法,直接创建一条edge的fixture,因为一般边不需要其他属性。默认边有摩擦力和弹力。

边也是以body中点为原点,所以边的起点和终点要用宽和高的一半来算。

这样添加后的碰撞种类(以player站在platform)上为例,可分为:

1. player的polygonShape和platform的topEdgeShape碰撞。

2. player的bottomEdgeShape和platform的polygonShape碰撞。

3. player的polygonShape和platform的polygonShape碰撞。

4. player的bottomEdgeShape和platform的topEdgeShape不会发生碰撞,因为他们都是Edge类型。

edgeShape的长度比polygonShape相应边的长度短一点,这样分别在判断左右两边和上下两边是否发生碰撞时,不会相互影响到。当rightEdge碰撞时,bottomEdge不会发生碰撞;当bottomEdge碰撞时,rightEdge也不会发生碰撞。

如果edgeShape的长度和polygonShape相应边的长度一样的话,当rightEdge碰撞时,bottomEdge的右端也会顶到墙上,发生碰撞,从而产生逻辑错误。比如:设定bottomShape发生碰撞时player的状态是isJump=NO,bottomEdge没有碰撞时isJump=YES。当player跳起并碰到墙壁时,isJump应该是YES状态,但bottomEdge检查到了碰撞,将isJump设为NO,这样player的其他行为和动作会发生错误。

或者把矩形polygonShape的直角顶点“切掉”,变成八边形。

如下图所示:


1.

 //DELTA_LENGTH = 0.5 
 //fixture1 with polygon shape
 b2PolygonShape rectShape;
 rectShape.SetAsBox(size.x/2/PTM_RATIO, size.y/2/PTM_RATIO);
 
 b2FixtureDef fixtureDef1;
 p_body->CreateFixture(&fixtureDef1);
 
 //fixture2 with edge shape
 b2EdgeShape edgeShape;
 edgeShape.Set(b2Vec2((-size.x/2 + DELTA_LENGTH)/PTM_RATIO, (-size.y/2)/PTM_RATIO), 
 b2Vec2((size.x/2 - DELTA_LENGTH)/PTM_RATIO, (s-size.y/2)/PTM_RATIO));
 
 b2FixtureDef fixtureDef2;
 fixtureDef2.shape = &edgeShape;
 p_bottomFixture = p_body->CreateFixture(&fixtureDef2);

2.

b2EdgeShape edgeShape;
 edgeShape.Set(b2Vec2((-size.x/2 + DELTA_LENGTH)/PTM_RATIO, (-size.y/2)/PTM_RATIO), 
 b2Vec2((size.x/2 - DELTA_LENGTH)/PTM_RATIO, (-size.y/2)/PTM_RATIO));

 p_bottomFixture = p_body->CreateFixture(&edgeShape, 0);

3 polygonShape必须是凸多边形,顶点按照逆时针方向依次给出

b2PolygonShape polygonShape;
 b2Vec2 vec[] = {b2Vec2(-size.x/2/PTM_RATIO, -size.y/2/PTM_RATIO), 
 b2Vec2(size.x/2/PTM_RATIO, -size.y/2/PTM_RATIO), 
 b2Vec2(size.x/2/PTM_RATIO, -size.y/4/PTM_RATIO), 
 b2Vec2(size.x/4/PTM_RATIO, size.y/2/PTM_RATIO), 
 b2Vec2(-size.x/4/PTM_RATIO, size.y/2/PTM_RATIO), 
 b2Vec2(-size.x/2/PTM_RATIO, -size.y/4/PTM_RATIO)};
 polygonShape.Set(vec, 6);
 b2FixtureDef fixtureDef1;
 fixtureDef1.shape = &polygonShape;
 fixtureDef1.density = dens;
 fixtureDef1.friction = f;
 fixtureDef1.restitution = rest;
 p_polygonFixture = p_body->CreateFixture(&fixtureDef1);
显示全文