在moveToParent函数之后,SKSpriteNode不保持当前位置

时间:2016-09-06 00:32:54

标签: ios sprite-kit

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

这是下一个屏幕,在触摸子节点之后:

enter image description here

2 个答案:

答案 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
输出后输出

enter image description here

现在,如果你这样做:

littleNode.moveToParent(bigNode2)

输出没有变化,完全如Apple所解释的那样。

更新(在0x141E评论之后):

@ 0x141E如您所见,该位置始终为10,10,所以它是正确的:

enter image description here

答案 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)