I’m trying to get to know when two sprites contact each other but I’m not being able to get it to work.
The code below reproduces the problem. I expected the contact delegate methods to fire when I tap the red square and the yellow square reaches it. However, nothing happens. The code seems like a lot but is actually quite simple. I’ve added comments to make it easier to read:
class GameScene: SKScene, SKPhysicsContactDelegate {
private var node: SKSpriteNode!
override func didMove(to view: SKView) {
// Set contact delegate to this class
physicsWorld.contactDelegate = self
// Have the Game Scene be the same size as the View
size = view.frame.size
// Create a yellow square with a volume based physics body that isn't dynamic
node = SKSpriteNode(color: .yellow, size: CGSizeMake(50, 50))
node.position = CGPointMake(100, 100)
node.physicsBody = SKPhysicsBody(rectangleOf: CGSizeMake(50, 50))
node.physicsBody!.isDynamic = false
// Set it's contact bit mask to any value (default category bitmask of
// SKSpriteNode is 0xFFFFFFFF so any value over here would do)
node.physicsBody!.contactTestBitMask = 1
// Add it to the Scene
addChild(node)
// Create a red square with a volume based physics body that isn't dynamic
let otherNode = SKSpriteNode(color: .red, size: CGSizeMake(50, 50))
otherNode.physicsBody = SKPhysicsBody(rectangleOf: CGSizeMake(50, 50))
otherNode.physicsBody!.isDynamic = false
// Set the position to be 100 pts to the right of the yellow square
otherNode.position = CGPointMake(200, 100)
// Add it to the Scene
addChild(otherNode)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// Moves yellow square to where you tapped on the screen
guard let finger = touches.first?.location(in: self) else { return }
node.run(.move(to: finger, duration: 1))
}
func didBegin(_ contact: SKPhysicsContact) {
print("did begin contact")
}
}
struct ContentView: View {
var body: some View {
VStack {
Text("Game")
SpriteView(scene: GameScene(), debugOptions: [.showsPhysics, .showsNodeCount])
}
.padding()
}
}
Can anyone tell me what I’m doing wrong?
Thanks in advance
2
Answers
When you’re using physics bodies, you should avoid moving nodes using actions. Instead move the bodies by setting forces and/or impulses, with methods like applyForce(_:) and applyImpulse(_:).
This will allow the physics engine to simulate the physics interactions correctly.
didBegin(contact:)
won’t fire if.isDynamic = false
so delete those lines and addphysicsWorld.gravity = .zero
to keep nodes from falling.