使用SpriteKit进行双重分派以进行碰撞处理 [英] Double dispatch for collision handling with SpriteKit

查看:244
本文介绍了使用SpriteKit进行双重分派以进行碰撞处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用SpriteKit的碰撞检测.它有一个如下所示的回调:

I'm using SpriteKit's collision detection. It has a callback that looks like this:

- (void)didBeginContact:(SKPhysicsContact *)contact

接触物体具有两个物理物体:

The contact object has two physics bodies:

SKPhysicsBody *bodyA;
SKPhysicsBody *bodyB;

我的游戏将有很多对象,当然我可以测试categoryBitMask来找出什么与什么冲突.但是考虑到我打算有很多种类(当然不超过32种)并且可能会动态引入新类型,那么进行动态双分派以对将导致碰撞,爆炸,得分等的逻辑进行编码的最优雅的方法是什么从所有这些碰撞中?当然,我可以构建一个巨大的毛发if语句,但是我希望有一些更干净的东西.

My game will have lots of objects, and of course I can test the categoryBitMask to find out what collided with what. But given that I intend to have many kinds (not more than 32 of course) and might dynamically introduce new types, what's the most elegant way to do dynamic double dispatch to code the logic for collisions, explosions, points scored, etc that will result from all these collisions? Of course I can build a giant hairy if-statement, but I was hoping for something cleaner.

也许是一个查找表,其中存储了适当处理程序的选择器?然后我用categoryBitMasks的某种组合索引查找表?我很想听听一些建议.

Maybe a lookup table storing selectors for the appropriate handlers? And then I index the lookup table by some combination of the categoryBitMasks? I'd love to hear some suggestions.

推荐答案

我创建了一个使用Pong作为我选择的游戏的SkPhysicsBodyContact的双重调度的工作示例.可以在我的github上找到工作代码.

I've created a working example of double dispatch for an SkPhysicsBodyContact using Pong as my game of choice. The working code is available on my github.

https://github.com/kouky/iOS-SpriteKit-Pong

实际上,您需要使用访问者"模式在您的联系人委托中执行双重调度,就像在Objective-C中一样,我们不能重载类方法的参数.

You actually need to use the Visitor pattern to perform the double dispatch in your contact delegate as in objective-c we can't overload class methods arguments.

- (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 是执行双重分派所需的中间商,它们非常简单,源代码位于项目存储库中.最终,它们使您可以拥有完全针对某些类型的节点处理联系人的类.

The VisitablePhysicsBody and ContactVisitor are middlemen required to perform the double dispatch, they're pretty simple and the source code is in the project repo. They ultimately allow you to have classes which are solely concenred with handling contacts for certain types of nodes.

例如,在我的Pong示例中,有一个名为 BallNodeContactVisitor 的类,该类仅在出现涉及 BallNode 的联系人时才接收消息.类中有一些遵循命名约定的方法,使我们能够确定与其他节点类型(例如,PaddleNode )的 BallNode 接触的结果.

For example in my Pong example there is a class called BallNodeContactVisitor which only receives messages when contacts arise which involve a BallNode. There are methods within the class which follow a naming convention and allow us to determine the outcome of the BallNode contact with other node types such as 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

这篇关于使用SpriteKit进行双重分派以进行碰撞处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆