0

我在碰撞检测方面遇到了一些问题。问题是碰撞被检测到太晚,当碰撞的两个物体相互重叠时。只有一个身体在移动,其他身体是静态的。身体通过 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
    }
}
} 

联系人监听器.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);

};

联系人监听器.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) {
}
4

2 回答 2

1

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

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

于 2013-08-01T17:08:16.807 回答
1

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

于 2013-08-02T11:17:39.543 回答