为什么会有多个碰撞调用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的parent是否为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) ?

最新更新