Box2D的Edge Shape的碰撞处理

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


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值