为什么有多个碰撞调用 Sprite Kit Swift

Why is there multiple collision calls Sprite Kit Swift

我正在构建一个 iOS swift 碰撞游戏。英雄正被来自屏幕右侧的小星星轰炸。每次星星击中英雄时,都会迭代分数并移除星星。但是,加分不止一分。

节点设置:

var star = SKSpriteNode(imageNamed: "star")
star.size = CGSizeMake(30, 30)
star.zPosition = 10
var starPhysicsRect = CGRectMake(star.position.x - star.frame.size.width / 2, star.position.y - star.frame.size.width / 2, star.frame.size.width, star.frame.size.height)
star.physicsBody = SKPhysicsBody(edgeLoopFromRect: starPhysicsRect)
star.physicsBody?.restitution = 0
star.name = "star"
star.physicsBody?.mass = 0
return star

didBeginContact 函数:

func didBeginContact(contact: SKPhysicsContact) {
    //collision variables
    var firstBodyNode = contact.bodyA.node as! SKSpriteNode
    var secondBodyNode = contact.bodyB.node as! SKSpriteNode
    var firstNodeName = firstBodyNode.name
    var secondNodeName = secondBodyNode.name

    //other variables
    var scoreLabel: SKLabelNode = constantsInstance.scoreLabel(position: CGPointMake(self.frame.size.width * 0.86, self.frame.size.height * 0.928))


    //check if hero hit star
    if firstNodeName == "hero" && secondNodeName == "star" {
        println("star hit")
        secondBodyNode.removeFromParent()

        //iterate score
        childNodeWithName("scoreLabel")?.removeFromParent()
        scoreLabel.text = "\(counterForScore)"
        counterForScore++
        self.addChild(scoreLabel)
    }
}

我也多次将 "star hit" 打印到控制台。为什么 didBeginContact 函数会被多次调用,如果我在第一次调用函数时删除星号?

我有 运行 较小规模的模拟,发现如果没有删除命令,星星会相当深入地进入英雄(因为 SKAction)。会不会是在星星进入英雄的过程中,在移除英雄之前,didBeginContact函数被调用了很多次?

非常感谢所有帮助。

您可以在继续之前检查 SKSpriteNode 的父级是否为 nil。

func didBeginContact(contact: SKPhysicsContact) {
    var firstBodyNode : SKSpriteNode!
    var secondBodyNode : SKSpriteNode!

    //  Assuming that the contact test bit mask of star is greater than hero. If it's not you should reverse the condition.

    if contact.bodyA.contactTestBitMask < contact.bodyB.contactTestBitMask {
        firstBodyNode = contact.bodyA.node as! SKSpriteNode
        secondBodyNode = contact.bodyB.node as! SKSpriteNode
    } else {
        firstBodyNode = contact.bodyB.node as! SKSpriteNode
        secondBodyNode = contact.bodyA.node as! SKSpriteNode
    }

    var firstNodeName = firstBodyNode.name
    var secondNodeName = secondBodyNode.name

    if firstNodeName == "hero" && secondNodeName == "star" {
        if secondBodyNode.parent != nil {
           // Your code.
        }
    }
}

莫非是physicsBody:

var star = SKSpriteNode(imageNamed: "star")
star.size = CGSizeMake(30, 30)
star.zPosition = 10
var starPhysicsRect = CGRectMake(star.position.x - star.frame.size.width / 2, star.position.y - star.frame.size.width / 2, star.frame.size.width, star.frame.size.height)
star.physicsBody = SKPhysicsBody(edgeLoopFromRect: starPhysicsRect)

看看创建 starPhysicsRect 的逻辑:

(star.position.x - star.frame.size.width / 2, star.position.y - star.frame.size.width / 2, star.frame.size.width, star.frame.size.height)

据我所知,这可以转换为以下值: (-15, -15, 30, 30) 那些负位置坐标看起来很奇怪。你确定你不只是想要: SKPhysicsBody(rectangleOfSize: star.size) 吗?