2 つの box2d ボディ間の接触を処理する接触リスナーがあります。box2d は、連絡先のボディを保存し、タイムステップ後に変更を実装することを推奨しているため、HelloWorldLayer の Contacter からボディにアクセスしています。以下のコードを参照してください。
Contacter.h:
#import "CCPhysicsSprite.h"
@interface Contacter : CCPhysicsSprite {
}
@property(nonatomic, assign) NSMutableArray* arrayOfBodies;
@property(nonatomic, assign) CCPhysicsSprite* spriteToDestroy;
-(void)physicsSpritesContact:(CCPhysicsSprite*)onePhysicsSprite otherSprite:(CCPhysicsSprite*)twoPhysicsSprite;
@end
コンタクタ.mm:
#import "Contacter.h"
#import "Box2D.h"
@implementation Contacter
@synthesize arrayOfBodies = _arrayOfBodies;
@synthesize spriteToDestroy = _spriteToDestroy;
-(void)destroyBodies:(b2Body*)body {
_arrayOfBodies = [[NSMutableArray alloc] init];
NSValue *bodyValue = [NSValue valueWithPointer:body];
[_arrayOfBodies addObject:bodyValue];
}
-(void)physicsSpritesContact:(CCPhysicsSprite*)onePhysicsSprite otherSprite: (CCPhysicsSprite*)twoPhysicsSprite; {
int firstTag = onePhysicsSprite.tag;
int secondTag = twoPhysicsSprite.tag;
if (((firstTag == 90) && (secondTag == 101 )) || ((firstTag == 101) && (secondTag == 90))) {
if (tag1 == 90) {
[self destroyBodies:onePhysicsSprite.b2Body];// adds body to array to be destroyed
spriteToDestroy = onePhysicsSprite; // taking note of sprite to be destroyed
}
else if (tag2 == 90) {
[self destroyBodies:twoPhysicsSprite.b2Body];
spriteToDestroy = twoPhysicsSprite;
}
}
}
HelloWorldLayer.mm 内の次のメソッドは update メソッドで呼び出されます。
-(void)removeDestroyedBodiesAndSprites {
bodyContact = [Contacter node];
if ([bodyContact arrayOfBodies]) {
for (NSValue* bodyValue in [bodyContact arrayOfBodies]) {
b2Body *removeBody;
removeBody = (b2Body*)[bodyValue pointerValue];
world->DestroyBody(removeBody);
removeBody = NULL;
[self removeChild:[bodyContact spriteToDestroy]];
}
}
}
接触はありますが、スプライトは削除されておらず、removeDestroyedBodiesAndSprites でボディが破壊されていません。CCLOG でテストした後、for ループが満たされていないことがわかりました。つまり、arrayOfBodies が null になる可能性があります。連絡先が確立されて以来、これは驚くべきことです。よろしくお願いします。
更新しました
以下は、連絡先リスナーです。
TestContactListener.h:
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#import "Box2D.h"
#import "GameObjects.h"
#import "Contacter.h"
class TestContactListener : public b2ContactListener {
public:
Contacter* contacter;
void BeginContact(b2Contact* contact);
};
TestContactListener.mm:
#import "TestContactListener.h"
void TestContactListener:: BeginContact(b2Contact *contact)
{
contacter = [Contacter node];
b2Fixture *fixtureA = contact->GetFixtureA();
b2Fixture *fixtureB = contact->GetFixtureB();
b2Body *fixtureABody = fixtureA->GetBody();
b2Body *fixtureBBody = fixtureB->GetBody();
CCPhysicsSprite* physicsSprite = (CCPhysicsSprite*)fixtureABody->GetUserData();
CCPhysicsSprite* physicsSprite2 = (CCPhysicsSprite*)fixtureBBody->GetUserData();
[contacter physicsSpritesContact:physicsSprite otherSprite:physicsSprite2];
}