视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Box2D的EdgeShape的碰撞处理
2020-11-09 08:09:48 责编:小采
文档

有时候两个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);

下载本文
显示全文
专题