Where do I put code that runs when two nodes collide or make contact with each other?
I've already read the article, "About Collisions and Contacts". That doesn't give me all the information I need.
Here is my code so far. The didBegin callback method isn't firing.
import UIKit
import SpriteKit
class GameScene: SKScene {
let player = SKSpriteNode(imageNamed: "player")
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
player.physicsBody = SKPhysicsBody(rectangleOf: player.size)
player.physicsBody?.isDynamic = false
player.physicsBody?.categoryBitMask = 0b00001
player.physicsBody?.collisionBitMask = 0b00001
player.position = CGPoint(x: 20 + player.size.width/2, y: view.frame.height / 2)
addChild(player)
let carEngineStart = SKAudioNode(fileNamed: "car_engine_running")
addChild(carEngineStart)
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(addCompetitor),
SKAction.wait(forDuration: 3.0)
])
))
}
override func update(_ currentTime: TimeInterval) {
let internalRollSign = TrialSpriteKit.sign(internalRoll)
switch internalRollSign {
case .zero:
print("0")
case .positive:
print("+")
if player.position.y < self.size.height {
player.position.y += 5
}
case .negative:
print("-")
if player.position.y > 0 {
player.position.y -= 5
}
}
}
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / /* 0xFFFFFFFF */ 4294967296)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
func addCompetitor() {
// Create sprite
let car = SKSpriteNode(imageNamed: "utili")
car.physicsBody = SKPhysicsBody(rectangleOf: car.size) // 1
car.physicsBody?.isDynamic = false
car.physicsBody?.categoryBitMask = 0b00001
car.physicsBody?.collisionBitMask = 0b00001
// Determine where to spawn the car along the Y axis
let actualY = random(min: car.size.height/2, max: size.height - car.size.height/2)
// Position the car slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
car.position = CGPoint(x: size.width + car.size.width/2, y: actualY)
// Add the car to the scene
addChild(car)
// Determine speed of the car
let actualDuration = random(min: CGFloat(2.0), max: CGFloat(4.0))
// Create the actions
let actionMove = SKAction.move(to: CGPoint(x: -car.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
let actionMoveDone = SKAction.removeFromParent()
car.run(SKAction.sequence([actionMove, actionMoveDone]))
}
}
extension GameScene: SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
print("BANG!")
}
}
The didBegin function is called when two physics bodies make contact. Place your collision handling code in didBegin or in its own function that you call from didBegin.
The tougher question is why didBegin is not being called. I noticed you have not set the contact test bit mask for your physics bodies. You need to set the contact bit mask to get notified when two physics bodies make contact. If that does not work, the following article from Hacking with Swift may help you:
hackingwithswift.com/read/11/5/collision-detection-skphysicscontactdelegate