addChild

时间:2016-11-07 08:44:13

标签: swift swift3 skspritenode arc4random

第一次编码器,我想我会开始使用Spritekit(Swift 3)进行游戏。我遇到了一个问题,当我向场景中添加一个精灵节点时,它会复制它。我还应该提到我这样做是一个重复发生的功能,我随机创建了四个障碍之一。

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

我已经在没有计时器且没有随机数生成的情况下对此进行了测试,并且它们都没有导致我相信其“选择”(切换或其他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 func传递也会创建两个节点。意思是这段代码

    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本身的问题?

1 个答案:

答案 0 :(得分:0)

The code above seems fine, you find a start position and then add a new child node, no problem there as far as I can see.

Now...you say:

except it always creates 2

So, will the above code add two childNodes?...it shouldn't :)

Maybe, and I'm guessing now, your problem is, that this code is run more than once? Remember that each time you call addChild(), it adds a new child node, no matter if there is a childNode already or not.

So it could be that you invoke the above code more than once and add a new childNode on top of an existing child node.

Removing a Child Node

If that is the case, and if you intend there to be only one childNode, then you could remove your wallTop1 from its parent before you add it again (I know, removing children from parents, programming is cruel sometimes ;)). A SKNode has the method removeFromParent() which you can use, so you could do something like:

...
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)
...

Or...if you don't want any childNodes at all, you can use removeAllChildren(), so...something like:

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)
...

Or, you could give your wallTop1 a name and then filter through your childNodes and find that node again:

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)

Hope that makes sense and helps you, good luck :)