【问题标题】:Box2D collision detectionBox2D 碰撞检测
【发布时间】:2013-08-01 11:36:59
【问题描述】:

我在碰撞检测方面遇到了一些问题。问题是碰撞检测为时已晚,当碰撞的两个物体相互重叠时。只有一个身体在移动,其他身体是静态的。身体通过 SetTransform() 函数移动并复制精灵的动作。这是我的 scheduleUpdate 方法和 ContactListener 类的代码

- (void)update:(ccTime)deltaTime {
std::vector<b2Body *>toDestroy;
std::vector<MyContact>::iterator pos;
for (pos=_contactListener->_contacts.begin();
     pos != _contactListener->_contacts.end(); ++pos) {
    MyContact contact = *pos;
    b2Body *bodyA = contact.fixtureA->GetBody();
    b2Body *bodyB = contact.fixtureB->GetBody();
    if (bodyA->GetUserData() != NULL && bodyB->GetUserData() != NULL) {
        CCSprite *spriteA = (CCSprite *) bodyA->GetUserData();
        CCSprite *spriteB = (CCSprite *) bodyB->GetUserData();
        // Contact detected between spriteA and spriteB
    }
}
} 

ContactListener.h

#import "Box2D.h"
#import <vector>
#import <algorithm>

struct MyContact {
b2Fixture *fixtureA;
b2Fixture *fixtureB;
bool operator==(const MyContact& other) const
{
    return (fixtureA == other.fixtureA) && (fixtureB == other.fixtureB);
}
};

class MyContactListener : public b2ContactListener {

public:
    std::vector<MyContact>_contacts;

    MyContactListener();
    ~MyContactListener();

    virtual void BeginContact(b2Contact* contact);
    virtual void EndContact(b2Contact* contact);
    virtual void PreSolve(b2Contact* contact, const b2Manifold* oldManifold);
    virtual void PostSolve(b2Contact* contact, const b2ContactImpulse* impulse);

};

ContactListener.mm

#import "MyContactListener.h"

MyContactListener::MyContactListener() : _contacts() {
}

MyContactListener::~MyContactListener() {
}

void MyContactListener::BeginContact(b2Contact* contact) {
// We need to copy out the data because the b2Contact passed in
// is reused.
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() };
_contacts.push_back(myContact);
}

void MyContactListener::EndContact(b2Contact* contact) {
MyContact myContact = { contact->GetFixtureA(), contact->GetFixtureB() };
std::vector<MyContact>::iterator pos;
pos = std::find(_contacts.begin(), _contacts.end(), myContact);
    if (pos != _contacts.end()) {
        _contacts.erase(pos);
    }
}

void MyContactListener::PreSolve(b2Contact* contact,
                             const b2Manifold* oldManifold) {
}

void MyContactListener::PostSolve(b2Contact* contact,
                              const b2ContactImpulse* impulse) {
}

【问题讨论】:

    标签: ios ios6 box2d-iphone


    【解决方案1】:

    我不建议将setTransform 用于移动物体。为了让一切正常工作,身体应该通过应用forces/impulses 来移动。如果您“手动”改变身体姿势,可能会发生奇怪的事情。

    也就是说,如果不实际尝试您的代码,很难知道发生了什么,但假设代码没问题(并且setTransform 与此无关),问题可能出在身体本身;我会开始检查你所有的体型是convex polygons

    【讨论】:

      【解决方案2】:

      是的,您不应该使用 setTransform 来移动身体,而应该像 ssantos 所说的那样使用力和冲动。也可能发生的情况是两个动态物体发生碰撞,在夹具重叠后检测到碰撞。为避免这种情况,您可以将主体设置为打开 CCD 的“子弹”,即连续碰撞检测。这更昂贵,因为不断评估该物体的碰撞,而不仅仅是在两个 AABB 重叠时。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-03-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多