SKNode
方法moveToParent
在移动到同一场景中的新父级后不会保持其绝对位置。节点移动到另一个位置。
moveToParent
的文档说
将节点移动到场景中的新父节点。节点在场景坐标中保持其当前位置。
我错过了什么吗?
update_01:
我意识到了一些新的东西。 移动节点只有在其初始位置为零点时才会保持其位置。如果它具有初始位置,则在moveToParent函数之后,它会移动,这使得我与apple文档相比感到困惑。
正如我从“维护”中理解的那样,它不会在屏幕上移动,只是它的位置值会发生变化。
并且请不要考虑场景!.scaleMode,因为它是在没有这个的情况下测试的(当然是正确的anchorPoint)并没有改变。
这是我的代码和截图:
导入SpriteKit
类GameScene:SKScene,UIGestureRecognizerDelegate {
var counter:Int = 0
var touchTracker : [UITouch : SKNode] = [:]
let yellowParentNode = SKSpriteNode()
let blueParentNode = SKSpriteNode()
override func didMoveToView(view: SKView)
{
scene!.scaleMode = SKSceneScaleMode.ResizeFill
let yellowPosition = CGPointMake(100, 100)
let bluePosition = CGPointMake(200[![enter image description here][1]][1], 100)
//yellow parent
yellowParentNode.name = "yellow"
yellowParentNode.color = UIColor.yellowColor()
yellowParentNode.size.height = 50
yellowParentNode.size.width = 50
yellowParentNode.anchorPoint = CGPoint(x: 0 , y: 0)
yellowParentNode.position = yellowPosition
self.addChild(yellowParentNode)
//blue parent
blueParentNode.name = "blue"
blueParentNode.color = UIColor.blueColor()
blueParentNode.size.height = 50
blueParentNode.size.width = 50
blueParentNode.position = bluePosition
blueParentNode.anchorPoint = CGPoint(x: 0 , y: 0)
self.addChild(blueParentNode)
//child
let childNode = SKSpriteNode()
childNode.color = UIColor.redColor()
childNode.size.width = 20
childNode.size.height = 20
childNode.name = "child"
childNode.position = CGPointMake(40, 40)
childNode.anchorPoint = CGPoint(x: 0 , y: 0)
yellowParentNode.addChild(childNode)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
let touch = touches.first as UITouch!
let touchLocation = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(touchLocation)
touchTracker[touch as UITouch] = touchedNode
if touchedNode.name == "child"
{
yellowParentNode.childNodeWithName("child")!.moveToParent(blueParentNode)
}
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?)
{
let touch = touches.first as UITouch!
let touchLocation = touch.locationInNode(self)
let touchedNode = touchTracker[touch as UITouch]
touchedNode?.position = touchLocation
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?)
{
// let touch = touches.first as UITouch!
touchTracker.removeAll()
}
override func update(currentTime: CFTimeInterval)
{
/* Called before each frame is rendered */
}
}
这是初始屏幕:
https://mitpress.mit.edu/books/introduction-algorithms
这是下一个屏幕,在触摸子节点之后:
答案 0 :(得分:0)
我认为对Apple提供的信息的解释可能存在误解。实际上&#34; 将节点移动到新的父节点 &#34;它可以理解您的节点已经是同一场景中节点的子节点。
如果您举例:
let pos1 = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame))
let pos2 = CGPointMake(CGRectGetMidX(self.frame)/2,CGRectGetMidY(self.frame)/2)
// make a big yellow node
let bigNode1 = SKSpriteNode.init(color: UIColor.yellowColor(), size: CGSizeMake(400,400))
addChild(bigNode1)
bigNode1.position = pos1
// make a big blue node
let bigNode2 = SKSpriteNode.init(color: UIColor.blueColor(), size: CGSizeMake(400,400))
addChild(bigNode2)
bigNode2.position = pos2
// make a little red node as a child of bigNode1
let littleNode = SKSpriteNode.init(color: UIColor.redColor(), size: CGSizeMake(100,100))
bigNode1.addChild(littleNode)
littleNode.position = CGPointZero
输出后输出:
现在,如果你这样做:
littleNode.moveToParent(bigNode2)
输出没有变化,完全如Apple所解释的那样。
更新(在0x141E评论之后):
@ 0x141E如您所见,该位置始终为10,10,所以它是正确的:
答案 1 :(得分:0)
你可能在这里被误导了,亚历山德罗的回答并没有解释为什么会发生这种情况。
position属性始终相对于父级。这不是场景坐标。如果要获取场景坐标,则需要将位置转换为场景。
现在,当您使用moveToParent时,您显然正在将节点的父属性移动到新父级。这意味着节点位置必须改变,因为父节点正在改变。现在节点位置必须改变才能调整新的父节点,因此它仍然停留在场景的同一位置。
E.G。
节点1位于10,10到场景,节点2位于20,10到场景。
节点A是节点1的子节点,位于0,0(场景坐标(10,10))
然后,我们将节点A从节点1移动到节点2.
如果位置永远不会改变(保持在(0,0)),这意味着当在屏幕上查看时,场景坐标将是20,10,这是错误的
该位置必须更改为(-10,0),因为您获取父级(20,10)并需要将其调整为(-10,0)以将节点A的场景坐标恢复为(10) ,10)