選択したゲームとして Pong を使用して、SkPhysicsBodyContact の二重ディスパッチの実例を作成しました。作業コードは、私の github で入手できます。
https://github.com/kouky/iOS-SpriteKit-Pong
object-c ではクラス メソッドの引数をオーバーロードできないため、実際には Visitor パターンを使用して contact デリゲートで二重ディスパッチを実行する必要があります。
- (void)didBeginContact:(SKPhysicsContact *)contact
{
SKPhysicsBody *firstBody, *secondBody;
firstBody = contact.bodyA;
secondBody = contact.bodyB;
VisitablePhysicsBody *firstVisitableBody = [[VisitablePhysicsBody alloc] initWithBody:firstBody];
VisitablePhysicsBody *secondVisitableBody = [[VisitablePhysicsBody alloc] initWithBody:secondBody];
[firstVisitableBody acceptVisitor:[ContactVisitor contactVisitorWithBody:secondBody forContact:contact]];
[secondVisitableBody acceptVisitor:[ContactVisitor contactVisitorWithBody:firstBody forContact:contact]];
}
VisitablePhysicsBodyとContactVisitorは、二重ディスパッチを実行するために必要な仲介者です。これらは非常にシンプルで、ソース コードはプロジェクト リポジトリにあります。最終的には、特定のタイプのノードの連絡先を処理することに専念するクラスを持つことができます。
たとえば、私の Pong の例では、 BallNodeContactVisitor というクラスがあり、 BallNodeを含む連絡先が発生したときにのみメッセージを受信します。クラス内には命名規則に従うメソッドがあり、BallNode と PaddleNode などの他のノード タイプとの接触の結果を判断できます。
@implementation BallNodeContactVisitor
// Handles contacts with PlayfieldScene edges
- (void)visitPlayfieldScene:(SKPhysicsBody *)playfieldBody
{
BallNode *ball = (BallNode *) self.body.node;
PlayfieldScene *playfield = (PlayfieldScene *) playfieldBody.node;
// Perform something
}
// Handles contacts with PaddleNodes
- (void)visitPaddleNode:(SKPhysicsBody *)paddleBody
{
BallNode *ball = (BallNode *) self.body.node;
PaddleNode *paddle= (PaddleNode *) paddleBody.node;
// Perform something else
}
@end