Objective c 如何使用cocos2d编写box2d联系人侦听器?
我一直在阅读关于如何编写联系人侦听器的各种教程,但我对此束手无策 以下是我到目前为止的情况: 在我代表一个物理对象的每个类中,我做:Objective c 如何使用cocos2d编写box2d联系人侦听器?,objective-c,cocos2d-iphone,box2d,Objective C,Cocos2d Iphone,Box2d,我一直在阅读关于如何编写联系人侦听器的各种教程,但我对此束手无策 以下是我到目前为止的情况: 在我代表一个物理对象的每个类中,我做: _body->SetUserData(self); 我编写了一个contact listener类,其中包含以下两种方法: void ContactListener::BeginContact(b2Contact* contact) { // Box2d objects that collided b2Fixture* fixtureA =
_body->SetUserData(self);
我编写了一个contact listener类,其中包含以下两种方法:
void ContactListener::BeginContact(b2Contact* contact)
{
// Box2d objects that collided
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
// Sprites that collided
MyNode* actorA = (MyNode*) fixtureA->GetBody()->GetUserData();
MyNode* actorB = (MyNode*) fixtureB->GetBody()->GetUserData();
}
void ContactListener::EndContact(b2Contact* contact)
{
// Box2d objects that collided
b2Fixture* fixtureA = contact->GetFixtureA();
b2Fixture* fixtureB = contact->GetFixtureB();
// Sprites that collided
MyNode* actorA = (MyNode*) fixtureA->GetBody()->GetUserData();
MyNode* actorB = (MyNode*) fixtureB->GetBody()->GetUserData();
}
我不知道下一步该怎么办。我现在有两个正在碰撞的精灵,但我想做以下事情:
1) 当它们碰撞时,我想根据对象的类型从世界上移除一个精灵。(例如,如果一个是cat对象,另一个是鼠标对象,我想删除鼠标对象
2) 我想让猫知道它吃了一只老鼠
3) 我希望猫继续移动,就好像它没有接触到鼠标一样
4) 我仍然不想让这只猫正常地与地形之类的东西相撞
我下一步做什么?我不知道该怎么办?如何让猫继续正常地与地形碰撞,而不是与鼠标碰撞?何时移除鼠标?拥有一个“实体”类来保存对Box2D主体的引用并对其进行操作,这绝对是一个好方法。如果你有一个宇宙飞船类和一个流星类,它们中的每一个都可以提供它们自己的控制身体(AI)的派生方法,但是它们都有共同的逻辑和代码来支持对“有身体的东西”的操作(例如共同的“实体”基类)。我认为你在正确的轨道上
当接触开始发生时,它变得有点模糊。这是您开始进入整个系统的架构的地方,而不仅仅是物理世界的结构或单个Coco2d场景
以下是我过去是如何做到这一点的:
首先,我设置了联系人侦听器,如下所示:
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)
{
b2Fixture* fixtureA = contact->GetFixtureA();
b2Body* bodyA = fixtureA->GetBody();
Entity* entityA = bodyA->GetUserData();
b2Fixture* fixtureB = contact->GetFixtureB();
b2Body* bodyB = fixtureB->GetBody();
Entity* entityB = bodyB->GetUserData();
if(test if entityA and entityB should not have collision response)
{
contact->SetEnabled(false);
}
// Do this if you want there to be collision notification, even if
// there is no response.
AddContactPair(entA,entB);
}
void AddContactPair(Entity* entA, Entity* entB)
{
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 BeginContact(b2Contact* contact)
{
Entity* entA = (Entity*)contact->GetFixtureA()->GetBody()->GetUserData();
Entity* entB = (Entity*)contact->GetFixtureB()->GetBody()->GetUserData();
assert(entA != NULL);
assert(entB != NULL);
// Not sure this is still needed if you add it in the pre-solve.
// May not be necessary...
AddContactPair(entA, entB);
}
// BEWARE: You may get multiple calls for the same event.
void EndContact(b2Contact* contact)
{
}
};
类EntityContactListener:公共ContactListener
{
私人:
游戏世界*\u游戏世界;
EntityContactListener(){}
类型定义结构
{
实体*entA;
实体*entB;
}接触线对;
矢量接触对;
公众:
虚拟~EntityContactListener(){}
EntityContactListener(游戏世界*游戏世界):
_游戏世界(gameWorld)
{
_触点对。保留(128);
}
void
{
讯息*msg;
MessageManager&mm=GameManager::Instance().GetMessageMgr();
对于(uint32 idx=0;idx<_contactPairs.size();idx++)
{
实体*entA=_contactPairs[idx].entA;
实体*entB=_contactPairs[idx].entB;
//DebugLogCPP(“联系通知%s%s”,entA->ToString().c_str(),entB->ToString().c_str());
msg=mm.CreateMessage();
msg->Init(entA->GetID(),entB->GetID(),Message::Message\u冲突);
mm.排队消息(msg,0);
msg=mm.CreateMessage();
msg->Init(entB->GetID(),entA->GetID(),Message::Message\u冲突);
mm.排队消息(msg,0);
}
_contactPairs.clear();
}
无效预溶解(b2Contact*contact,常数b2Manifold*oldManifold)
{
b2Fixture*fixtureA=contact->GetFixtureA();
b2Body*bodyA=fixtureA->GetBody();
实体*entityA=bodyA->GetUserData();
b2Fixture*fixtureB=contact->GetFixtureB();
b2Body*bodyB=fixtureB->GetBody();
实体*entityB=bodyB->GetUserData();
if(测试entityA和entityB是否不应具有冲突响应)
{
联系人->设置启用(错误);
}
//如果希望有冲突通知,请执行此操作,即使
//没有回应。
添加触点对(entA、entB);
}
void AddContactPair(实体*entA,实体*entB)
{
对于(uint32 idx=0;idx<_contactPairs.size();idx++)
{
if(_contactPairs[idx].entA==entA&&u contactPairs[idx].entB==entB)
回来
//不确定是否需要这个。。。
if(_contactPairs[idx].entA==entB&&u contactPairs[idx].entA==entB)
回来
}
接触线对;
pair.entA=entA;
pair.entB=entB;
_触点对。推回(对);
}
//注意:同一事件可能会有多个呼叫。
无效BeginContact(b2Contact*contact)
{
实体*entA=(实体*)联系人->GetFixtureA()->GetBody()->GetUserData();
实体*entB=(实体*)联系人->GetFixtureB()->GetBody()->GetUserData();
断言(entA!=NULL);
断言(entB!=NULL);
//如果将其添加到预解算中,则不确定是否仍需要此项。
//可能没有必要。。。
添加触点对(entA、entB);
}
//注意:同一事件可能会有多个呼叫。
无效结束触点(b2Contact*触点)
{
}
};
由于引擎的工作方式,你可以得到多个相同的机构接触点击。此侦听器对它们进行过滤,因此如果两个实体发生冲突,您只会收到一条消息
侦听器仅存储发生的冲突。为了其他目的,可以对其进行修改,将其进一步分为“开始”和“结束”。在这里,“接触”的意思是“你被什么东西击中了”。我不需要知道它是否停止了联系
这就是所谓的“秘密酱汁”。它向两个联系的实体(通过消息系统)发送一条消息,表明他们击中了某个对象,而另一个实体就是他们击中的对象。子弹击中了船。子弹毁灭自我。基于子弹属性(getDamageIncomputed()方法)进行自我伤害。这进而向图形系统发出信号,要求将项目符号从显示屏上移除。如果船被毁了,它也会被毁
从整体执行的角度来看:
开始之前,请指定联系人侦听器
游戏的每个周期:
对所有实体调用“更新”。这更新了他们的物理力等。
更新Box2d世界。
在侦听器上调用notify。
从系统中删除死实体
这有用吗?我还是迷路。我有3个实体-猫,老鼠,地形。猫鼠手