我遇到了一个我无法弄清楚的非常奇怪的错误.在我的游戏中,你驾驶一辆2D飞机上的汽车试图避开障碍物(如岩石或汽车).障碍可以出现在3条不同的路径上.有时在任何路径上只有一个障碍物,或者有时在三条路径中的两条路径上存在两个障碍物.
我遇到的问题是,当两个障碍出现然后当它们离开屏幕时被删除时,屏幕上当前移动的障碍之一也被“删除”(我知道这是因为控制台打印“已删除的对象”3次).但是,随机“删除”的障碍不会从视图中删除.相反,它冻结了以前的地方,永远不会消失.
这是我遇到问题的代码块:
var canGetScore = true
for (num,obj) in enumerate(obstaclesToMove) {
obj.position.y -= CGFloat(gameSpeed)
if obj.position.y <= userCar.position.y && obj.name == "NotPassed" {
obj.name = "Passed"
if canGetScore {
canGetScore = false
score += 1
scoreLabel.text = "\(score)"
}
}
if obj.position.y <= -CGRectGetMidY(self.frame) {
obj.removeFromParent()
obstaclesToMove.removeAtIndex(num)
println("deleted object")
}
}
变量键:
>“barriersToMove”是一系列障碍物(SKSpriteNodes),应该向下移动到屏幕上.
>“gameSpeed”是屏幕每帧移动多少像素的整数(在此实例中值为5).
>“userCar”是用户控制的字符(SKSpriteNode).
“canGetScore”的目的是消除我之前遇到的另一个错误.我知道这不是导致我当前的错误.
有没有人知道为什么会这样?如果您需要更多解释,请询问.
额外注意:用户的汽车技术上从不移动,但背景和障碍物移动.
最佳答案 在我看来,问题在于如何从obstoToMove中删除你的对象
想象一下,你的数组中有三个对象:
obstaclesToMove = [object1, object2, object3]
你必须删除对象1& 2,因为它们必须离开屏幕,所以你在代码中做的是首先删除对象1然后删除对象2,除了在你的代码中它转换为:
obstaclesToMove.removeAtIndex(0)
obstaclesToMove.removeAtIndex(1)
您会认为这不是问题,除非您在执行此操作时查看阵列会发生什么:
obstaclesToMove = [object1, object2, object3]
obstaclesToMove.removeAtIndex(0)
// obstaclesToMove = [object2, object3]
obstaclesToMove.removeAtIndex(1)
// obstaclesToMove = [object2]
通常,从正在循环的数组中删除对象是个坏主意.你可以做些什么让它更安全:
>收集数组中需要删除的所有索引
>按相反顺序对它们进行排序
>从数组中删除项目
你可以这样做:
var indexToDelete: [MyObstacleObject] = []
var canGetScore = true
for (num,obj) in enumerate(obstaclesToMove) {
obj.position.y -= CGFloat(gameSpeed)
if obj.position.y <= userCar.position.y && obj.name == "NotPassed" {
obj.name = "Passed"
if canGetScore {
canGetScore = false
score += 1
scoreLabel.text = "\(score)"
}
}
if obj.position.y <= -CGRectGetMidY(self.frame) {
indexToDelete.append(num)
}
}
indexToDelete.sort({ $0 > $1 })
for item in indexToDelete {
obstaclesToMove[item].removeFromParent()
obstaclesToMove.removeAtIndex(item)
println("deleted object")
}
这样,当您从阵列中删除项目时,您可以确保它们仍然具有正确的索引,因为您将首先删除具有更高索引的项目.