在我的xcode项目中,我正在尝试创建一个在SKShapeNode点击我创建的世界边界(屏幕边缘)时调用的函数。由于重力,SKShapeNode击中屏幕边缘并向右滚动,但是当接触完成时,函数didBeginContact不会被调用。这是我的代码
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
struct PhysicsCategory {
static let redBall: UInt32 = 0x1 << 1
static let blueBall: UInt32 = 0x1 << 2
static let worldBorder: UInt32 = 0x1 << 3
}
let slimeBall = SKSpriteNode(imageNamed: "slimeBall")
let lilyPete = SKSpriteNode(imageNamed:"golden")
override func didMoveToView(view: SKView) {
self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame)
self.physicsWorld.gravity = CGVectorMake(1, 5)
self.physicsBody?.categoryBitMask = PhysicsCategory.worldBorder
self.physicsBody!.node?.name = "world"
self.backgroundColor = UIColor.darkGrayColor()
let playerCircle = SKShapeNode(circleOfRadius: 15)
playerCircle.name = "blueCircle"
playerCircle.fillColor = UIColor.blueColor()
playerCircle.strokeColor = UIColor.blackColor()
playerCircle.position = CGPointMake(self.frame.size.width / 2, self.frame.size.height / 2)
playerCircle.physicsBody?.categoryBitMask = PhysicsCategory.redBall
playerCircle.physicsBody?.contactTestBitMask = PhysicsCategory.worldBorder | PhysicsCategory.redBall
playerCircle.physicsBody?.collisionBitMask = PhysicsCategory.blueBall | PhysicsCategory.worldBorder
addChild(playerCircle)
let enemyCircle = SKShapeNode(circleOfRadius: 50)
enemyCircle.name = "redCircle"
enemyCircle.fillColor = UIColor.redColor()
enemyCircle.strokeColor = UIColor.blackColor()
enemyCircle.physicsBody = SKPhysicsBody(circleOfRadius: 50)
enemyCircle.position = CGPointMake(self.frame.size.width / 3, self.frame.size.height / 2)
enemyCircle.physicsBody?.affectedByGravity = true
enemyCircle.physicsBody?.dynamic = true
enemyCircle.physicsBody!.mass = 0.05
enemyCircle.physicsBody?.categoryBitMask = PhysicsCategory.blueBall
enemyCircle.physicsBody?.contactTestBitMask = PhysicsCategory.worldBorder | PhysicsCategory.blueBall
enemyCircle.physicsBody?.collisionBitMask = PhysicsCategory.worldBorder | PhysicsCategory.blueBall
addChild(enemyCircle)
enemyCircle.physicsBody?.applyForce(CGVectorMake(-2, -3))
}
func didBeginContact(contact: SKPhysicsContact) {
let firstBody = contact.bodyA
let secondBody = contact.bodyB
if(contact.bodyA.node?.name == "redCircle") && (contact.bodyB.node?.name == "world") || (contact.bodyA.node?.name == "world") && (contact.bodyB.node?.name == "redCircle"){
print("Contact Made")
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first! as UITouch
let touchLocation = touch.locationInNode(self)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.first! as UITouch
let touchLocation = touch.locationInNode(self)
}
}
答案 0 :(得分:0)
您的红色圆圈的类别位掩码为blueBall
,其联系位掩码仅与worldBorder
和其他blueBall
进行交互。您的蓝色圆圈的类别位掩码为redBall
,并且只会与worldBorder
和其他blueBall
联系。
将您的红色圆圈类别设为实际为redBall
,并将您的蓝色圆圈类别设为实际为blueBall
,然后您的所有碰撞都应为工作。您可能希望再次运行您的位掩码,因为这两个被交换以确保一切都与其他所有内容发生冲突,因为您没有提及应该如何设置它。
但是,在didBeginContact
方法中,您没有正确地包装if语句检查(IMO)。事实上,你完全没有。我建议将支票包裹起来:
if ((contact.bodyA.node?.name == "redCircle") && (contact.bodyB.node?.name == "world")) || ((contact.bodyA.node?.name == "world") && (contact.bodyB.node?.name == "redCircle")) {
这将检查||
一侧的所有内容到另一侧的所有内容,然后这将允许您的&&
自己驻留,只检查其括号对中的所有内容。
答案 1 :(得分:0)
在DidMoveToView中你需要调用
physicsWorld.contactDelegate = self
否则Contact方法永远不会触发。
此外,对于你的玩家圈子,你没有给它像
这样的物理体 playerCircle.physicsBody = SKPhysicsBody(...)
将DidBeginContact方法改为此方法,这样您就不必为每次碰撞做2次检查。还可以使用PhysicsCategory来识别它们而不是名称。
func didBeginContact(contact: SKPhysicsContact) {
var firstBody: SKPhysicsBody
var secondBody: SKPhysicsBody
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
}
if (firstBody.categoryBitMask == PhysicsCategory.redBall) && (secondBody.categoryBitMask == PhysicsCategory.worldBorder) {
// red ball hit world border, do something
}
if (firstBody.categoryBitMask == PhysicsCategory.blueBall) && (secondBody.categoryBitMask == PhysicsCategory.worldBorder) {
// blue ball hit world border, do something
}
}
另外作为一个提示,在一些物理实体上,你用力展开!
self.physicsBody!.node?.name = "world"
enemyCircle.physicsBody!.mass = 0.05.
如果没有找到physicsBody,会导致崩溃。
总是使用它更好吗?只要你可以,你已经为大多数人做过了。
在给他们一个物理实体之前,也尝试给你的精灵他们的位置,否则你会得到一些意想不到的结果。
enemyCircle.position = CGPointMake(self.frame.size.width / 3, self.frame.size.height / 2)
enemyCircle.physicsBody = SKPhysicsBody(circleOfRadius: 50)
enemyCircle.physicsBody.categoryBitMask = ...
...
希望这有帮助