gpt4 book ai didi

ios - 当射弹击中两个 "monsters"时,didBeginContact 方法崩溃。我知道为什么,但我不知道如何避免

转载 作者:行者123 更新时间:2023-11-28 13:11:42 28 4
gpt4 key购买 nike

所以我从教程中得到了这段代码:

func didBeginContact(contact: SKPhysicsContact) {

// 1
var firstBody: SKPhysicsBody?
var secondBody: SKPhysicsBody?
var body: SKPhysicsBody

//contact.bodyB.node!.physicsBody!.allContactedBodies().count


if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
firstBody = contact.bodyA
secondBody = contact.bodyB
println("1 = A, 2 = B")
} else {
firstBody = contact.bodyB
secondBody = contact.bodyA
println("2 = A, 1 = B")
}



// 2
if ((firstBody!.categoryBitMask & PhysicsCategory.Monster != 0) &&
(secondBody!.categoryBitMask & PhysicsCategory.Projectile != 0)) {

for var c = 1; c <= contact.bodyB.node!.physicsBody!.allContactedBodies().count; c++ {
projectileDidCollideWithMonster(firstBody!.node as! SKSpriteNode, monster: secondBody!.node as! SKSpriteNode)

}
secondBody!.node?.removeFromParent()
}
}

func projectileDidCollideWithMonster(projectile:SKSpriteNode, monster:SKSpriteNode) {
println("Hit")
changeScore(1)
changeAmo(true)
projectile.removeFromParent()
monster.removeFromParent()
}

然后发生的事情是,弹丸有时会同时击中两个怪物。

发生这种情况时 - didBeginContact 方法崩溃并提示 secondBody 为 nil。

经过深入研究,我发现了原因:

当弹丸同时与其他两个节点碰撞时 - 此方法运行两次。第一次运行后 - 如果将 bodyA 作为射弹,将 bodyB 作为怪物 - 将它们传递给 projectileDidCollideWithMonster 并将它们都删除。然后它立即再次运行,但在那一刻射弹不再存在并且它崩溃无法分配它的节点。

我不知道如何克服这个问题:(有什么建议吗?

解决方案:感谢以下想法,我做了一些更改。

在类的顶部添加数组和触发器:

    var bodiesToBeRemoved = [SKSpriteNode]()
var shouldRemoveBodies = false

并做了这些修改:

 func projectileDidCollideWithMonster(projectile:SKSpriteNode, monster:SKSpriteNode) {
/* Called when collisions is detected and collided nodes are passed to it */
//score and stuff
println("Hit")
changeScore(1)
changeAmo(true)

//collect the nodes to be removed
bodiesToBeRemoved.append(projectile)
bodiesToBeRemoved.append(monster)

//change the trigger to remove collected nodes later on
shouldRemoveBodies=true

}

override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */

//check the trigger
if shouldRemoveBodies == true {
println("\(bodiesToBeRemoved.count)")
//remove collected nodes
for var i = 0; i<bodiesToBeRemoved.count; i++ {
bodiesToBeRemoved[i].removeFromParent()
}

//reset array
bodiesToBeRemoved.removeAll(keepCapacity: false)

//reset the trigger
shouldRemoveBodies = false
} else {
//do nothing:)
}

}

最佳答案

不是立即移除你的抛射物,而是将其标记为移除(例如,通过设置一个 bool 标志,或者如果它不在集合中则将其添加到某个集合中)。然后,在下一次物理检查之前(例如在本帧的末尾),检查并移除所有标记为移除的射弹。

关于ios - 当射弹击中两个 "monsters"时,didBeginContact 方法崩溃。我知道为什么,但我不知道如何避免,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31057866/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com