在我的快速代码中,左右按钮下方围绕一个名为“棍”的节点移动。我希望当用户点击使棍子与边界相交的按钮时。调试部分将打印“flag”。我知道 uikit 中有一个 intersect 命令,但我不知道 sprite kit 中有一个。青色是界限
class GameScene: SKScene {
var stick: SKSpriteNode!
var leftButton: SKSpriteNode!
var rightButton: SKSpriteNode!
var bounds: SKSpriteNode!
override func didMove(to view: SKView) {
backgroundColor = SKColor.white
// Create and position the stick
stick = SKSpriteNode(color: .brown, size: CGSize(width: 160, height: 20))
stick.position = CGPoint(x: size.width * -0.2, y: size.height * -0.1)
addChild(stick)
bounds = SKSpriteNode(color: .systemTeal, size: CGSize(width: 150, height: 300))
bounds.position = CGPoint(x: size.width * -0.4, y: size.height * -0.2)
addChild(bounds)
// 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)
}
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)
}
}
}
}
我认为在这种情况下相交不是一个选择。
SpriteKit 有一个检测系统,可以告诉您两个节点何时相互接触。您可以通过使类符合
SKPhysicsContactDelegate
来向类添加接触检测回调。
例如。
class ContactDetectionLogic: SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
print("flag")
}
}
您甚至可以使您自己的
GameScene
符合此协议! (我通常这样做,而且我认为这是非常典型的做法)
class GameScene: SKScene, SKPhysicsContactDelegate {
// ...blah blah blah all the other code
func didBegin(_ contact: SKPhysicsContact) {
print("flag")
}
}
一旦决定了哪个对象将接收回调,请确保将此对象分配给
delegate
中的 physicsWorld
属性。
例如:
var objectThatHandlesContactLogic: ContactDetectionLogic!
override func didMove(to view: SKView) {
objectThatHandlesContactLogic = ContactDetectionLogic()
physicsWorld.delegate = objectThatHandlesContactLogic
backgroundColor = SKColor.white
}
或者如果您使场景本身符合委托(这又是更典型的事情),您会这样做:
override func didMove(to view: SKView) {
physicsWorld.delegate = self // This is also much cleaner imo
backgroundColor = SKColor.white
}
添加委托后,您必须配置哪些节点接触会触发它们。在你的情况下,它是棍子和界限,所以你这样做:
override func didMove(to view: SKView) {
physicsWorld.contactDelegate = self
physicsWorld.gravity = .zero
backgroundColor = SKColor.white
// Create and position the stick
let stickSize = CGSize(width: 60, height: 20)
stick = SKSpriteNode(color: .brown, size: stickSize) stick.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
addChild(stick)
// Add physics body to stick
stick.physicsBody = SKPhysicsBody(rectangleOf: stickSize)
stick.physicsBody!.categoryBitMask = 0b0000 // Means the stick belongs to no category (all zeros)
stick.physicsBody!.collisionBitMask = 0b0000 // Means the stick collides with no category (all zeros)
stick.physicsBody!.contactTestBitMask = 0b0001 // Means the stick will only collide with nodes belonging to category 0001 (in binary, which also happens to mean category "1" in decimal)
// Create and position the bounds box
let boundsSize = CGSize(width: 150, height: 150)
bounds = SKSpriteNode(color: .systemTeal, size: boundsSize)
bounds.position = CGPoint(x: size.width * 0.5, y: size.height * 0.35)
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
}
现在,每当联系开始时,您都应该收到一个打印“标记”的信息。