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;
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.
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.
Why not inspect SKNode subclasses?
Then you can easily inspect for contacted
body.node
classes. Then create a configuration dictionary that gives you what method to call.Some node subclasses...
...then create methods like...
...then create a configuration like...
So you can check for containments of the contacted bodies, then instantiate a selector with
NSSelectorFromString
, then call it withperformSelector:withObject:withObject:
.It may be optimized, normalized in may ways, but feels me as a way clean solution. Have not proofed yet, just came across.
Just noticed you just wrote almost the same at the end of the question itself. Will post it anyway. :D Wow, the comment suggestions just does the same. Aw.
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
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.
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.
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.
Following is how the contact dispatch works in Kobold Kit.
The gist of it: you send each contacting node a message
didBeginContact:withOtherBody:
so each node on its own knows with which other body it made or lost contact. If you need the other body's node, you can get that from the SKPhysicsBodynode
property.