0

衝突検出に問題があります。問題は、衝突する 2 つの物体が互いに重なっている場合、衝突の検出が遅すぎることです。SetTransform()関数でスプライトの動きをコピーして体を動かします。これが、scheduledUpdate メソッドと 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) {
}
4

2 に答える 2

1

setTransform体を動かす目的での使用はお勧めしません。すべてが正常に機能するためには、体に適用することで体が動くはずforces/impulsesです。体の位置を「手動で」変更すると、奇妙なことが起こる可能性があります。

とは言っても、実際にコードを試してみないと何が起こっているのかを知るのは難しいですが、コードが問題ないと仮定すると (そしてそれsetTransformは何も関係ありません)、問題は本体自体にある可能性があります。私はあなたのすべての体型がconvex polygons.

于 2013-08-01T17:08:16.807 に答える