In my swift code below, a left and right button that moves around a node called stick. I would like when the user hits the button that makes stick intersect with bounds. The debug section will print "flag". I know in uikit there is an intersect command, but I don't know withe sprite kit. The teal is bounding.
import SpriteKit
import GameplayKit
class GameScene: SKScene , SKPhysicsContactDelegate {
var stick: SKSpriteNode!
var leftButton: SKSpriteNode!
var rightButton: SKSpriteNode!
var bounds: SKSpriteNode!
var objectThatHandlesContactLogic: ContactDetectionLogic!
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self // << from the previous step
backgroundColor = SKColor.white
objectThatHandlesContactLogic = ContactDetectionLogic()
physicsWorld.contactDelegate = objectThatHandlesContactLogic
// Create left and right buttons
leftButton = SKSpriteNode(color: .blue, size: CGSize(width: 100, height: 50))
leftButton.position = CGPoint(x: size.width * 0.2, y: size.height * 0.1)
addChild(leftButton)
rightButton = SKSpriteNode(color: .red, size: CGSize(width: 100, height: 50))
rightButton.position = CGPoint(x: size.width * -0.1, y: size.height * 0.1)
addChild(rightButton)
// Create and position the stick
physicsWorld.contactDelegate = self // << from the previous step
backgroundColor = SKColor.white
// Create and position the stick
let stickSize = CGSize(width: 160, height: 20)
stick = SKSpriteNode(color: .brown, size: stickSize)
stick.position = CGPoint(x: size.width * -0.2, y: size.height * -0.1)
addChild(stick)
// Add physics body to stick
stick.physicsBody = SKPhysicsBody(rectangleOf: stickSize)
stick.physicsBody!.categoryBitMask = 0b0000 // Means the stick doesn't belong to any category (all zeros)
stick.physicsBody!.collisionBitMask = 0b0000 // Means the stick collides with no category, i.e., doesn't collide with anything (all zeros)
stick.physicsBody!.contactTestBitMask = 0b0001 // Means the stick will only collide with nodes belonging to category 0001 (in binary. This also happens to mean category "1" in decimal)
stick.physicsBody!.affectedByGravity = false // since you dont want it falling off of the screen
// Create and position the bounds box
let boundsSize = CGSize(width: 150, height: 300)
bounds = SKSpriteNode(color: .systemTeal, size: boundsSize)
bounds.position = CGPoint(x: size.width * -0.4, y: size.height * -0.2)
addChild(bounds)
// add physics body to bounds
bounds.physicsBody = SKPhysicsBody(rectangleOf: boundsSize)
bounds.physicsBody!.collisionBitMask = 0b0000 // Means bounds collides with no category (all zeros)
bounds.physicsBody!.categoryBitMask = 0b0001 // Means the bounds belongs to category 0001 (in binary. Which again, translates to "1" in decimal), which if you remember, is what we set the stick to collide with
// the default value for bounds.physicsBody!.contactBitMask
// is already 0b0000 so no need to set it explicitly here.
// (You could do it for consistency sake if you'd like but it
// wouldn't matter since you're setting it to the same value it
// already is)
bounds.physicsBody!.affectedByGravity = false // since you dont want it falling off of the screen
// ...blah blah blah all the other code
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches {
let location = touch.location(in: self)
if leftButton.contains(location) {
// Rotate the stick counterclockwise
let rotateAction = SKAction.rotate(byAngle: CGFloat(Double.pi / 4), duration: 1.0)
stick.run(rotateAction)
print("hit Left")
}
if rightButton.contains(location) {
// Rotate the stick clockwise
let rotateAction = SKAction.rotate(byAngle: -CGFloat(Double.pi / 4), duration: 1.0)
stick.run(rotateAction)
}
}
}
}
class ContactDetectionLogic: NSObject, SKPhysicsContactDelegate { // << Make sure you also add NSObject
// if you add this function, this function will be called when a contact between two nodes begins
func didBegin(_ contact: SKPhysicsContact) {
print("flag")
}
}
I don't think an intersection is an option in this case.
Step 1:
SpriteKit has a detection system that can tell you when two nodes come into contact with one another. You can add contact detection callbacks to a class by conforming that class to the
SKPhysicsContactDelegate.eg.
you could even conform your own
GameSceneto this protocol! (I usually do this and I think this is pretty typical to do)Step 2:
Once you've decided which object will receive callbacks make sure you assign this object to the
delegateproperty in yourphysicsWorld.eg:
or if you conformed the scene itself to the protocol (which again, is the more typical thing to do), you would do:
Step 3:
Once you've added the delegate you have to configure which nodes coming in contact would trigger them. In your case its the stick and the bounds so you do so we add physics bodies to each of them:
Now you should get a print saying "flag" whenever a contact begins.
Hopefully this helped! If you have questions about how the contact system works just leave a comment and I'll answer them