I wrote the following code to detect collisions between the player, a wall and a npc:
struct PhysicsCategories{
static let player: UInt32 = 0x1 << 1
static let npc: UInt32 = 0x1 << 2
static let wall: UInt32 = 0x1 << 3
static let all: UInt32 = 0xFFFFFFFF
}
self.physicsBody!.categoryBitMask = Constants.PhysicsCategories.player
self.physicsBody!.collisionBitMask = Constants.PhysicsCategories.npc | Constants.PhysicsCategories.wall
self.physicsBody!.contactTestBitMask = Constants.PhysicsCategories.npc
tileNode.physicsBody!.categoryBitMask = Constants.PhysicsCategories.wall
tileNode.physicsBody!.collisionBitMask = Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc
npc.physicsBody!.categoryBitMask = Constants.PhysicsCategories.npc
npc.physicsBody!.collisionBitMask = Constants.PhysicsCategories.wall | Constants.PhysicsCategories.player | Constants.PhysicsCategories.npc
npc.physicsBody!.contactTestBitMask = Constants.PhysicsCategories.player
If I understood correctly, you want the player and the NPC to "bounce off the walls", but not bounce off each other. The solution would be to not set their collisionBitMasks to each other‘s categoryBitMasks, but only their contactTestBitMasks.
As to why the NPC needs to be dynamic to bounce off the walls: One participant must be dynamic for a collision to show effect: the one that bounces off.