gpt4 book ai didi

cocos2d-iphone - 在没有连续碰撞的情况下检测两个 box2d 物体的初始碰撞

转载 作者:行者123 更新时间:2023-12-03 18:04:25 24 4
gpt4 key购买 nike

我有一些简单的 box2d 主体设置,带有一个联系人监听器,如下所示:

#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);


b2Body *A = contact->GetFixtureA()->GetBody();
b2Body *B = contact->GetFixtureA()->GetBody();

NSLog(@"Collision detected!");
PLAYSOUND(COLLISION);

}

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) {

}

当两个物体相撞时,我需要播放声音。但是,此实现会检测到连续碰撞,因此当 body 接触时会播放声音。我对 box2d 和 C++ 的知识已经非常有限了,有没有一种简单的方法可以在不检测连续碰撞的情况下检测新的碰撞?

最佳答案

你有正确的基本想法,但它需要一些改进。

在您的 BeginContact(...) 电话中,您有:

PLAYSOUND(COLLISION);

您应该做的不是在此处播放声音,而是将其他系统排入队列以播放此特定对的声音。将主体的 userdata 标记设置为指向类的指针(或其他一些 ID 以跟踪实体)。像这样:
class EntityContactListener : public ContactListener
{
private:
GameWorld* _gameWorld;
EntityContactListener() {}

typedef struct
{
Entity* entA;
Entity* entB;
} CONTACT_PAIR_T;

vector<CONTACT_PAIR_T> _contactPairs;

public:
virtual ~EntityContactListener() {}

EntityContactListener(GameWorld* gameWorld) :
_gameWorld(gameWorld)
{
_contactPairs.reserve(128);
}

void NotifyCollisions()
{
Message* msg;
MessageManager& mm = GameManager::Instance().GetMessageMgr();

for(uint32 idx = 0; idx < _contactPairs.size(); idx++)
{
Entity* entA = _contactPairs[idx].entA;
Entity* entB = _contactPairs[idx].entB;

//DebugLogCPP("Contact Notification %s<->%s",entA->ToString().c_str(),entB->ToString().c_str());

msg = mm.CreateMessage();
msg->Init(entA->GetID(), entB->GetID(), Message::MESSAGE_COLLISION);
mm.EnqueueMessge(msg, 0);

msg = mm.CreateMessage();
msg->Init(entB->GetID(), entA->GetID(), Message::MESSAGE_COLLISION);
mm.EnqueueMessge(msg, 0);
}
_contactPairs.clear();
}

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

}

// BEWARE: You may get multiple calls for the same event.
void BeginContact(b2Contact* contact)
{
Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
//DebugLogCPP("Begin Contact %s->%s",entA->ToString().c_str(),entB->ToString().c_str());
if(entA->GetGroupID() == entB->GetGroupID())
{ // Can't collide if they are in the same group.
return;
}

assert(entA != NULL);
assert(entB != NULL);

for(uint32 idx = 0; idx < _contactPairs.size(); idx++)
{
if(_contactPairs[idx].entA == entA && _contactPairs[idx].entB == entB)
return;
// Not sure if this is needed...
if(_contactPairs[idx].entA == entB && _contactPairs[idx].entA == entB)
return;
}
CONTACT_PAIR_T pair;
pair.entA = entA;
pair.entB = entB;
_contactPairs.push_back(pair);
}

// BEWARE: You may get multiple calls for the same event.
void EndContact(b2Contact* contact)
{
/*
Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
DebugLogCPP("End Contact %s->%s",entA->ToString().c_str(),entB->ToString().c_str());
*/
}
};

最后一部分是到 不是 即使发生碰撞,也会在短时间内再次播放声音。您可以通过创建秒表或从实体更新周期的固定时间开始倒计时来实现此目的。

这个有帮助吗?

关于cocos2d-iphone - 在没有连续碰撞的情况下检测两个 box2d 物体的初始碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8978084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com