Я установил контактный слушатель, который создает сварное соединение, когда устанавливается контакт между двумя телами. Когда тела касаются, я продолжаю получать SIGABRT, указывающий на линию
b2Assert(IsLocked() == false);
в методе
b2Joint* b2World::CreateJoint(const b2JointDef* def)
в классе
b2World.cpp
Вот классы контактов слушателя:
SubcContactListener.h:
#import <Foundation/Foundation.h>
#import "cocos2d.h"#import "Box2D.h"#import "Spriter.h"#import "CreateRope.h"
class SubcContactListener : public b2ContactListener {
public:
void *helloWorldLayer;
b2WeldJoint *weldJoint;
b2World *world;
void BeginContact(b2Contact* contact);
void EndContact(b2Contact* contact);
void createWeldJoint(b2Body* ABody ,b2Body* BBody);
//void destroyWeldJoint(b2WeldJoint *weldJoint);
};
SubcContactListener.mm:
#import "SubcContactListener.h"#import "HelloWorldLayer.h"
void SubcContactListener:: BeginContact(b2Contact *contact) {
}
void SubcContactListener:: EndContact(b2Contact *contact) {
b2Fixture *fixtureA = contact->GetFixtureA();
b2Fixture *fixtureB = contact->GetFixtureB();
b2Body *fixtureABody = fixtureA->GetBody();
b2Body *fixtureBBody = fixtureB->GetBody();
// We don't care about collisions that don't involve two bodies.
if (helloWorldLayer && fixtureABody && fixtureBBody)
{
if(fixtureABody != NULL && fixtureBBody != NULL){
createWeldJoint(fixtureABody, fixtureBBody);
}
}
}
void SubcContactListener:: createWeldJoint(b2Body* ABody ,b2Body* BBody) {
// The sprite tag is 1 for the spriter sprite and 3 for the rope links.
if (ABody && BBody)
//{
CCSprite *bodyASprite = (CCSprite *) ABody->GetUserData();
CCSprite *bodyBSprite = (CCSprite *) BBody->GetUserData();
NSInteger bodyASpriteTag = bodyASprite.tag;
NSInteger bodyBSpriteTag = bodyBSprite.tag;
if (((bodyASpriteTag == 1) && (bodyBSpriteTag == 3)) ||
((bodyASpriteTag == 3) && (bodyBSpriteTag == 1)))
{
//creation of weldjoint
if ( ABody!= NULL && BBody != NULL) {b2WeldJointDef weldJointDef;
weldJointDef.Initialize(ABody,
BBody,
ABody->GetWorldCenter());
weldJointDef.collideConnected = false;
weldJoint = (b2WeldJoint*) ABody->GetWorld()->CreateJoint(&weldJointDef);
}
}
}
}
Также в рамках метода initWhysics HelloWorldLayer.mm:
// Create contact listener
contactListener = new SubcContactListener();
contactListener->helloWorldLayer = self;
world->SetContactListener(contactListener);
Из-за ошибки я думаю, что это как-то связано со сварным соединением, но не слишком уверен. Пожалуйста помоги.
Вам не разрешено изменять мир внутри обратного вызова. Утверждение assert утверждает, что оно заблокировало мир для начала шага симуляции, поэтому вам не разрешено выполнять эту операцию.
Эта проблема решается путем кэширования событий контактов и их обработки после шага моделирования.
Других решений пока нет …