为什么同一个SKNode层中的对象不能相互交互?

时间:2016-08-24 03:10:44

标签: swift sprite-kit

我使用SpriteKit的时间不到1年,所以直到最近才将SKNodes用作图层。

我有一个SKNode图层,可以保存所有鱼和用户的位置,例如:

var layerMainGame = SKNode()
layerMainGame.zPosition = 50
layerMainGame.addChild(userPosition)
layerMainGame.addChild(pipFish)
addChild(layerMainGame)

使用此功能处理用户是否接触到鱼的交互,这基本上是检查他们的帧是否交叉:

if CGRectIntersectsRect(CGRectInset(node.frame, delta.dx, delta.dy), self.userPosition.frame) {
    print("You got hit by \(name).")
    gameOver()
}

有效。 userPosition和pipFish之间的交互有效。什么是行不通的是随着游戏的进行而添加的鱼。我有一个函数在这样的间隔中产生不同类型的鱼:

func spawnNew(fish: SKSpriteNode) {
    layerMainGame.addChild(fish)
}

用户和稍后在游戏中添加到同一层的鱼之间的交互不起作用。我可以直接通过他们,没有比赛结束。当我完全删除整个layerMainGame变量并将它们像正常一样添加到场景中时,所有交互都起作用。将它们全部添加到同一个SKNode层不起作用。

这是为每条鱼创造命中碰撞的功能。

func createHitCollisionFor(name: String, GameOver gameOver: String!, delta: (dx: CGFloat, dy: CGFloat), index: Int = -1) {
    enumerateChildNodesWithName(name) { [unowned me = self] node, _ in
        if CGRectIntersectsRect(CGRectInset(node.frame, delta.dx, delta.dy), self.userPosition.frame) {
            me.gameOverImage.texture = SKTexture(imageNamed: gameOver)
            didGetHitActions()
            me.runAction(audio.playSound(hit)!)
            if index != -1 {
                me.trophySet.encounterTrophy.didEncounter[index] = true
            }
            print("You got hit by \(name).")
        }
    }
}

我称之为:

createHitCollisionFor("GoldPiranha", GameOver: model.gameOverImage["Gold"], delta: (dx: 50, dy: 50), index: 1)

当鱼不在图层中时它起作用,但当它们添加到图层时不起作用。

1 个答案:

答案 0 :(得分:4)

当节点放置在节点树中时,其position属性将其置于其父节点提供的坐标系中。

Sprite Kit使用从屏幕左下角开始的坐标方向(0,0),当你向上和向右移动时,x和y值会增加。

  • 对于 SKScene ,原点的默认值 - anchorPoint为(0,0),它对应于视图框架矩形的左下角。要将其更改为中心,您可以指定(0.5,0.5)

  • 对于 SKNode ,坐标系原点由其anchorPoint定义,默认为(0.5,0.5),它是节点的中心。

    < / LI>

在你的项目中你有layerMainGame例如添加到场景中,他的anchorPoint默认为(0.5,0.5)所以像你的鱼一样的孩子的起源是中心,你可以看到它如果你改变鱼的位置如下:

func spawnNew(fish: SKSpriteNode) {
    layerMainGame.addChild(fish)
    fish.position = CGPointZero // position 0,0 = parent center 
}

希望有助于了解如何解决您的问题。

更新 :(更改主要问题后)

为了帮助您更好地了解会发生什么,我会马上给出一个例子:

override func didMoveToView(view: SKView) {
        var layerMainGame = SKNode()
        addChild(layerMainGame)

        let pipFish = SKSpriteNode(color: UIColor.yellowColor(), size: CGSizeMake(50,50))
        pipFish.name = "son"
        self.addChild(pipFish)

        let layerPipFish = SKSpriteNode(color: UIColor.yellowColor(), size: CGSizeMake(50,50))
        layerPipFish.name = "son"
        layerMainGame.addChild(layerPipFish)

        enumerateChildNodesWithName("son") { [unowned me = self] node, _ in
            print(node)
        }
}

输出

enter image description here

现在我只想更改一行:

layerMainGame.addChild(layerPipFish)

使用:

self.addChild(layerPipFish)

<强>输出

enter image description here

发生了什么事?

正如您所看到的enumerateChildNodesWithName被写为您和我的代码仅打印直接添加到self的子项(因为实际上我们启动enumerateChildNodesWithName它等于启动self.enumerateChildNodesWithName

如何在完整节点树中搜索?

如果您有一个名为&#34; GoldPiranha&#34;的节点然后在名称前加一个you can search through all descendants。所以你会搜索&#34; // GoldPiranha&#34;:

enumerateChildNodesWithName("//GoldPiranha") { [unowned me = self] ...
相关问题