At the moment, I use SKPhysicsContact to trigger a change in behaviour for my sprites, from within the GameScene. The problem is with each development, the game scene becomes longer and longer. Has anyone managed to make a GKComponent with SKPhysics embedded in it to make contact management simpler? How would this work?
1 Answers
Collision handling is difficult to handle well in an entity-component architecture because of the single point of dispatch (the physics world's contact delegate). But you can use that point to sort out involved entities and dispatch contact messages to the correct components.
Apple's DemoBots sample code has one example of this. Here's a quick summary of how they do it:
SK nodes for which contact handling is desired use a special subclass,
EntityNode
, which adds a back-reference to the node's owning entity (GKEntity
or some subclass).In
didBeginContact
, sort out whether the contact wants handling and by whom. DemoBots does this by creating aColliderType
struct that helps to abstract the bit masks into "does type A want to collide / notify contacts with type B?" kinds of questions.After deciding who to notify, work out the owning entities/components for the colliding sprites and send contact messages on to them. That is, your custom entity or component classes should define their own contact handling messages.
DemoBots uses a bunch of custom entity classes and handles contacts in each. You could just as well use fewer entity classes, and handle contacts in a component — in which case your step 3 above would involve looking up the ContactComponent
(or whatever you call it) on the colliding entities and sending messages to them.

- 124,678
- 26
- 272
- 326
-
DemoBots is very complex. Working from it though, I've (1) copied the ColliderType struct into my code, (2) added the handleContact methods (and calls to didBeginContact, didEndContact) in my GameScene, (3) added the PhysicsComponent to each of my entities, (4) copied the contactNotifiableType protocol, (5) defined the contacts (and collisions) using loadResourcesWithCompletionHandler in each entity class, and (6) added the func contactWithEntityDidBegin: From running some prints in this func and looking at sprite behaviour, I can see the contacts and collisions aren't getting acted on. – Shane O'Seasnain Jan 17 '16 at 09:57
-
I have also added the EntityNode from DemoBots, and included a let reference in my SpriteComponent to this. I've added a few prints and it looks like bitmasks are not getting assigned to the entity's physicsBodies. I've tried to force this by moving the .requestedContactNotifications in the init: of each entity. When I force this and print the contents of requestedContactNotifications from ColliderType, the array is populated with the requested contact pairings. Is there another way to debug this? – Shane O'Seasnain Jan 17 '16 at 10:53
-
A bit more information: I've run a print from within GameScene's update method and see the physicsbody isn't being set for the nodes. I've also run a print within the copy of PhysicsComponent and see that the masks are being added to the physicsbodies. It looks like the problem is the SKSpriteNodes' physicsbody property isn't being set to the physicsbody being created in the PhysicsComponent. Any idea what part of DemoBots is matching these two physicsbodies up? – Shane O'Seasnain Jan 17 '16 at 12:06
-
SOLVED: I noticed that DemoBots matches the RenderComponent's physicsBody to the PhysicsComponent's – Shane O'Seasnain Jan 17 '16 at 12:44