Swift 3(SpriteKit):图像更改时,SKShapeNode不移动

Swift 3(SpriteKit):图像更改时,SKShapeNode不移动,swift,sprite-kit,skshapenode,Swift,Sprite Kit,Skshapenode,我遇到了一个关于SKShapeNodes的问题,我很难理解。为了帮助解释和展示我的问题,我创建了一个测试程序。开始时,我创建了一行,如下所示: var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)] var Line = SKShapeNode(points: &points, count: points.count) addChild(Line) points = [CGPoint(x: -372, y: -50),

我遇到了一个关于SKShapeNodes的问题,我很难理解。为了帮助解释和展示我的问题,我创建了一个测试程序。开始时,我创建了一行,如下所示:

var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)]
var Line = SKShapeNode(points: &points, count: points.count)
addChild(Line)
points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
Line = SKShapeNode(points: &points, count: points.count)
Line.position.y = Line.position.y - 200
print("LINEPOS =", Line.position)
此时,我可以更改节点的位置,并打印出我期望的位置:

Line.position.y = Line.position.y - 50
print("LINEPOS =", Line.position)
它打印:

LINEPOS=(0.0,-50.0)

这是有意义的,因为SKShapeNode的原始位置始终是(0,0)。但是,程序的下一部分的工作方式不同。我使新的点等于现在屏幕上直线所在位置的坐标,并让直线等于它们,如下所示:

var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)]
var Line = SKShapeNode(points: &points, count: points.count)
addChild(Line)
points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
Line = SKShapeNode(points: &points, count: points.count)
Line.position.y = Line.position.y - 200
print("LINEPOS =", Line.position)
然后我再次改变线条的位置(这次我将其向下移动了200,因此位置的变化更明显),如下所示:

var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)]
var Line = SKShapeNode(points: &points, count: points.count)
addChild(Line)
points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
Line = SKShapeNode(points: &points, count: points.count)
Line.position.y = Line.position.y - 200
print("LINEPOS =", Line.position)
它打印:

LINEPOS=(0.0,-200.0)

即使它正确地打印了位置,很明显,这条线在屏幕上根本没有移动。它仍然处于与我让线等于新点时相同的位置。这意味着,在让SKShapeNode等于一组新的点之后,它不再在屏幕上移动,而是在它所说的代码中移动

我怎样才能解决这个问题?如果有人知道,请帮助我,因为我真的很困惑。

只需检查一下

import SpriteKit
    var Line:SKShapeNode!
    class GameScene: SKScene {
        override func didMoveToView(view: SKView) {
            /* Setup your scene here */
            var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)]
           Line = SKShapeNode(points: &points, count: points.count)
            addChild(Line)

        }

        override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
           /* Called when a touch begins */
           Line.position.y = Line.position.y + 200

        }

        override func update(currentTime: CFTimeInterval) {
            /* Called before each frame is rendered */
        }
    }
导入SpriteKit
变量行:SKShapeNode!
类游戏场景:SKScene{
覆盖func didMoveToView(视图:SKView){
/*在这里设置场景*/
var points=[CGPoint(x:-372,y:0),CGPoint(x:372,y:0)]
Line=SKShapeNode(点:&points,计数:points.count)
addChild(行)
}
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
/*当触摸开始时调用*/
Line.position.y=Line.position.y+200
}
覆盖函数更新(currentTime:CFTimeInterval){
/*在渲染每个帧之前调用*/
}
}
尝试以下代码:

import SpriteKit

class GameScene:SKScene {

override func didMove(to view: SKView) {

    var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)]
    var Line = SKShapeNode(points: &points, count: points.count)
    addChild(Line)

    Line.position.y = Line.position.y - 50
    print("LINEPOS =", Line.position)

    points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
    Line.removeFromParent()

    Line = SKShapeNode(points: &points, count: points.count)
     addChild(Line)
    Line.position.y = Line.position.y - 200
    print("LINEPOS =", Line.position)

    }
}
从您的代码中,当您第二次执行类似于
Line=SKShapeNode=…
的操作时,将创建新的形状,它还没有父形状。它不在节点树中。您看到的是旧形状,它没有从父对象中删除。所以,删除那个,然后添加一个新的。。。或者,不要每次都创建新形状,只需更改其位置即可

此外,这可能有点令人困惑。即使你删除了一行,上面写着:

Line.removeFromParent()
代码将编译(但您将看到两行)

因此,即使您处理的是同一个变量,并且一个节点只能有一个父节点,但如果您不从父节点中删除该行,则代码仍会编译,然后再进行另一个
addChild(Line)
调用。这怎么可能

这是因为:

  • 创建一行,该行是对
    SKShapeNode
    的引用,该节点在创建后立即添加到父节点。现在,因为它被添加到树中,所以有另一个引用指向它,因为它是场景的
    子数组的一部分

  • 然后再次实例化一个行变量,因此现在它显示在内存中不同的
    SKShapeNode
    上(但旧的
    SKShapeNode
    仍在树中)。这个新的SKShapeNode没有添加到树中,它的父属性是nil。因此,您可以将其再次添加到树中,而无需编译器对您大喊大叫

  • 编辑:

    要回应您关于如何更改SKShapeNode路径的评论,您可以执行以下操作:

    var points = [CGPoint(x: -372, y: 0), CGPoint(x: 372, y: 0)]
    var Line = SKShapeNode(points: &points, count: points.count)
    addChild(Line)
    
    points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
    Line = SKShapeNode(points: &points, count: points.count)
    
    Line.position.y = Line.position.y - 200
    print("LINEPOS =", Line.position)
    
    let path=CGMutablePath()


    谢谢你的代码,但是在我第一次将skshapenode设置为不同的值之后,我特别遇到了这个问题。当skshapenode在屏幕上不移动时。@dragoneye问题是OP多次实例化一个行变量。请看我的例子。对不起,我认为我错了whirlwind是对的。您需要从父层次结构中删除子对象,并为其指定一个新值。谢谢!现在我明白多了。那么,您是否建议删除节点然后添加一个新节点是更改节点图像的最佳方式?因此,在我再次更改skshapenode的值之前,我必须将其从其父节点中删除?@J.Treutlein这取决于您尝试执行的操作。这不是必须的,当然也不是规则。但是在你的情况下,为了得到想要的效果,是的,你必须这样做。@J.Treutlein个人来说,我不知道你为什么要再次重新创建一个节点?您不应该仅仅为了改变节点的位置而重新实例化一个完整的节点。这不是一种性能上的方法。因为我想改变节点的图像(换句话说:使它看起来不同)。