我使用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)
当鱼不在图层中时它起作用,但当它们添加到图层时不起作用。
答案 0 :(得分:4)
当节点放置在节点树中时,其position属性将其置于其父节点提供的坐标系中。
Sprite Kit使用从屏幕左下角开始的坐标方向(0,0),当你向上和向右移动时,x和y值会增加。
对于 SKScene ,原点的默认值 - anchorPoint
为(0,0),它对应于视图框架矩形的左下角。要将其更改为中心,您可以指定(0.5,0.5)
对于 SKNode ,坐标系原点由其anchorPoint
定义,默认为(0.5,0.5),它是节点的中心。
在你的项目中你有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)
}
}
输出:
现在我只想更改一行:
layerMainGame.addChild(layerPipFish)
使用:
self.addChild(layerPipFish)
<强>输出强>:
发生了什么事?
正如您所看到的enumerateChildNodesWithName被写为您和我的代码仅打印直接添加到self
的子项(因为实际上我们启动enumerateChildNodesWithName
它等于启动self.enumerateChildNodesWithName
)
如何在完整节点树中搜索?
如果您有一个名为&#34; GoldPiranha&#34;的节点然后在名称前加一个you can search through all descendants。所以你会搜索&#34; // GoldPiranha&#34;:
enumerateChildNodesWithName("//GoldPiranha") { [unowned me = self] ...