【问题标题】:unwanted duplications with addChildaddChild 不必要的重复
【发布时间】:2016-11-18 17:44:56
【问题描述】:

第一次编码,我想我会从 Spritekit (Swift 3) 的游戏开始。我遇到了一个问题,当我将精灵节点添加到场景时,它会复制它。我还应该提到我这样做是作为一个重复出现的功能,我随机创建四个障碍之一。

我设置了一个定时机制来使函数定期运行。 func 然后从 0-3 生成一个随机数,然后使用 switch/case 方法,该方法应该只创建四个选项中的一个,但它总是创建 2 个(仍然是随机的,因此它可能是 2 个重复项或 2 个单独的选项重叠)。我也尝试过“if, else if...”语句,结果相同。

我已经在没有计时器和随机数生成的情况下对此进行了测试,它们都不是问题,导致我相信它要么是“选择”(switch 或 else if)方法,要么我使用 addChild 错误。

关于问题可能是什么的任何想法,或随机生成精灵的替代解决方案?

提前致谢!

此代码还有很多内容,但我已将其简化为熊的基本要素,但我仍然得到重复。

let movementAmount = arc4random() % UInt32(self.frame.height / 2)
let wallOffset = CGFloat(movementAmount) - self.frame.height / 4

let xCoordinate = self.frame.midX
let yCoordinate = self.frame.midY + (self.frame.height / 2) + wallOffset


wallTop1 = SKSpriteNode(texture: wallTop1Tex)
wallTop1.scale(to: CGSize(width: wallTop1Tex.size().width / 2, height: wallTop1Tex.size().height / 2))
wallTop1.position = CGPoint(x: xCoordinate, y: yCoordinate)
wallTop1.zPosition = objectZPos
addChild(wallTop1)

更新:我做了更多的测试,结果证明,至少根据节点数,即使不涉及随机性,每个 addChild 函数传递都会创建两个节点。意思是这段代码

    let xCoordinate = self.frame.midX
    let yCoordinate = self.frame.midY
    objectTex = SKSpriteTexture(imageNamed: "object")
    object = SKSpriteNode(texture: objectTex)
    object.position = CGPoint(x: xCoordinate, y: yCoordinate)
    self.addChild(object)

在我的 sprite kit 版本中创建了两个节点,我只能假设这是一个小故障,除非我有一些未知的设置错误??如果是这样,我很想听听它是什么,如果不是,我可以运行某种类型的去毛刺/调试来解决 SpriteKit 本身似乎存在的问题吗?

【问题讨论】:

  • 欢迎加入 :) 您是否介意将导致您遇到问题的代码添加到您的问题中,这样我们可以更轻松地了解正在发生的事情。
  • @pbodsk 我已经添加了代码,如果您需要任何其他信息,请告诉我。谢谢!

标签: swift swift3 skspritenode arc4random


【解决方案1】:

上面的代码看起来很好,你找到一个起始位置然后添加一个新的子节点,据我所知没有问题。

现在……你说:

除了它总是创建 2

那么,上面的代码会添加两个 childNodes 吗?...它不应该 :)

也许,我现在猜,你的问题是,这段代码运行了不止一次?请记住,每次调用 addChild() 时,它都会添加一个新的子节点,无论是否已经存在 childNode。

因此,您可能多次调用上述代码并在现有子节点之上添加一个新的 childNode。

删除子节点

如果是这种情况,并且如果您打算只有一个 childNode,那么您可以在再次添加之前从其父节点中删除您的 wallTop1(我知道,从父节点中删除子节点,编程有时是残酷的; ))。 SKNode 具有您可以使用的 removeFromParent() 方法,因此您可以执行以下操作:

...
if wallTop1 != nil && wallTop1.parent != nil {
    wallTop1.removeFromParent()
}
//And then your "add new node code"
wallTop1 = SKSpriteNode(texture: wallTop1Tex)
wallTop1.scale(to: CGSize(width: wallTop1Tex.size().width / 2, height:wallTop1Tex.size().height / 2))
wallTop1.position = CGPoint(x: xCoordinate, y: yCoordinate)
...

或者...如果您根本不想要任何子节点,您可以使用removeAllChildren(),所以...类似于:

removeAllChildren()
//And then your "add new node code"
wallTop1 = SKSpriteNode(texture: wallTop1Tex)
wallTop1.scale(to: CGSize(width: wallTop1Tex.size().width / 2, height:wallTop1Tex.size().height / 2))
wallTop1.position = CGPoint(x: xCoordinate, y: yCoordinate)
...

或者,您可以给您的wallTop1 一个name,然后通过您的childNodesfilter 并再次找到该节点:

let childNodeName = "somethingCleverHere"
let existingChildren = children.filter { $0.name == childNodeName}
if existingChildren.count > 0 {
   removeChildrenIn(existingChildren!)
}

//And then your "add new node code"
wallTop1 = SKSpriteNode(texture: wallTop1Tex)
wallTop1.scale(to: CGSize(width: wallTop1Tex.size().width / 2, height:wallTop1Tex.size().height / 2))
wallTop1.position = CGPoint(x: xCoordinate, y: yCoordinate)
wallTop1.zPosition = objectZPos
//Remember to give it a name
wallTop1.name = childNodeName
addChild(wallTop1)

希望这有意义并帮助你,祝你好运:)

【讨论】:

  • 除非我误解了您的回答,否则我认为这不会有帮助。我将多次运行此代码,然后使用 skActionSequence,沿屏幕移动它们,然后 removeFromParent 它们,同时创建和移动其他代码。我的问题是,即使我现在已经去掉了这些部分,我仍然有两个孩子使用我上面发布的固定代码。这只是一个小故障吗?在这一点上,除了随机生成与 addChild 函数混淆之外,我想不出其他任何东西???再次感谢:)
  • 对不起,第一次没有回复你,我看到你的评论,然后又忘记了。即使您只调用一次addChild,您也会添加两个节点,这似乎很奇怪,所以我认为错误一定在其他地方。我注意到您写道:“我已经在没有计时器和没有随机数生成的情况下对此进行了测试,它们都不是问题,导致我相信它要么是“选择”(switch 或 else if)方法”。但我在您提供的代码示例中看不到任何与“选择”相关的内容。那个代码还存在吗?
  • 没问题,虽然我没有正确标记它是我再次发布它的唯一原因。但是你是对的,“选择”方法不是问题,因为代码现在不存在。我想我只能等待 Swift 的更新,希望它能解决这个问题。或者想出一种全新的方式来生成精灵。我见过一种方法,您可以完全使用要复制的精灵创建另一个父文件,删除子文件,然后将其添加到主父屏幕。所以我可能会试一试。
猜你喜欢
  • 2019-05-07
  • 2017-12-18
  • 2020-07-20
  • 1970-01-01
  • 2021-12-28
  • 2013-08-22
  • 2011-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多