【问题标题】:Swift 3 (SpriteKit): SKShapeNode not moving when its image is changedSwift 3(SpriteKit):SKShapeNode 在其图像更改时不移动
【发布时间】:2017-05-04 02:24:27
【问题描述】:

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

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)

打印出来:

LINEPOS = (0.0, -50.0)

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

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

然后我再次改变 Line 的位置(这次我将它向下移动了 200,因此位置的变化更加明显),如下所示:

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

打印出来:

LINEPOS = (0.0, -200.0)

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

我该如何解决这个问题?如果有人知道请帮忙,因为我真的很困惑。

【问题讨论】:

    标签: swift sprite-kit skshapenode


    【解决方案1】:

    只检查一次

    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 */
            }
        }
    

    【讨论】:

    • 感谢您的代码,但在我第一次将 skshapenode 设置为不同的东西后,我特别遇到了这个问题。那是 skshapenode 不在屏幕上移动的时候。
    • @dragoneye 问题是 OP 多次实例化 Line 变量。看看我的例子。
    • 对不起,我认为我理解错了旋风是正确的,您需要从父层次结构中删除子级并为其分配一个新值
    【解决方案2】:

    试试这个代码:

    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) 调用之前不从父节点中删除 Line,代码仍然可以编译。这怎么可能?

    嗯,这是因为:

    1. 您创建一个 Line,它是对 SKShapeNode 的引用,该 SKShapeNode 在创建后立即添加到父级。现在,因为它被添加到树中,所以有另一个引用指向它,因为它是场景的children 数组的一部分。

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

    编辑:

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

    让路径 = CGMutablePath()

    points = [CGPoint(x: -372, y: -250), CGPoint(x: 372, y: -250)]
    
    path.move(to: CGPoint(x: points[0].x, y: points[0].y))
    
    path.addLine(to: CGPoint(x: points[1].x, y: points[1].y))
    
    Line.path = path
    

    【讨论】:

    • 非常感谢!现在我明白了很多。那么您是否建议删除节点然后添加一个新节点是更改节点图像的最佳方法?
    • 那么在我再次更改 skshapenode 的值之前,我必须将其从其父节点中移除?
    • @J.Treutlein 这真的取决于你想要做什么。这不是必须的,当然也不是规则。但在你的情况下,为了获得想要的效果,是的,你必须这样做。
    • @J.Treutlein 个人不知道为什么要重新创建一个节点?您不应该仅仅为了改变它的位置而重新实例化一个完整的节点。不是一种高效的方式。
    • 因为我想改变节点的图像(换句话说:让它看起来不一样)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多