Swift 3 (SpriteKit): SKShapeNode 在其图像改变时不移动
Swift 3 (SpriteKit): SKShapeNode not moving when its image is changed
我遇到了一个我很难理解的 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)。但是,该程序的下一部分不会以相同的方式工作。我使新点等于线现在在屏幕上的坐标,并让线等于它们,如下所示:
points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
Line = SKShapeNode(points: &points, count: points.count)
然后我再次改变直线的位置(这次我将它向下移动了 200,所以位置的变化更明显)像这样:
Line.position.y = Line.position.y - 200
print("LINEPOS =", Line.position)
它打印:
LINEPOS = (0.0, -200.0)
即使它正确地打印了位置,但很明显 Line 在屏幕上根本没有移动。它仍然与我让线等于新点时的位置相同。这意味着在让 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 */
}
}
试试这个代码:
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()
代码将编译(但您会看到两行)。
因此,即使您正在处理同一个变量并且一个节点只能有一个父节点这一事实,如果您不从父节点中删除 Line,代码仍然可以编译,然后再创建另一个 addChild(Line)
打电话。这怎么可能?
好吧,因为这个才有效:
您创建了一个引用 SKShapeNode
的行,该行在创建后立即添加到父级。现在,因为它被添加到树中,所以有另一个引用指向它,因为它是场景的 children
数组的一部分。
然后你再次实例化一个 Line 变量,所以现在它显示在内存中不同的 SKShapeNode
上(但旧的 SKShapeNode
仍在树中)。这个新的 SKShapeNode 没有添加到树中,它的父属性是 nil。因此,您可以将它再次添加到树中,而无需编译器对您大喊大叫。
编辑:
要回应您关于如何更改 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
我遇到了一个我很难理解的 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)。但是,该程序的下一部分不会以相同的方式工作。我使新点等于线现在在屏幕上的坐标,并让线等于它们,如下所示:
points = [CGPoint(x: -372, y: -50), CGPoint(x: 372, y: -50)]
Line = SKShapeNode(points: &points, count: points.count)
然后我再次改变直线的位置(这次我将它向下移动了 200,所以位置的变化更明显)像这样:
Line.position.y = Line.position.y - 200
print("LINEPOS =", Line.position)
它打印:
LINEPOS = (0.0, -200.0)
即使它正确地打印了位置,但很明显 Line 在屏幕上根本没有移动。它仍然与我让线等于新点时的位置相同。这意味着在让 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 */
}
}
试试这个代码:
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()
代码将编译(但您会看到两行)。
因此,即使您正在处理同一个变量并且一个节点只能有一个父节点这一事实,如果您不从父节点中删除 Line,代码仍然可以编译,然后再创建另一个 addChild(Line)
打电话。这怎么可能?
好吧,因为这个才有效:
您创建了一个引用
SKShapeNode
的行,该行在创建后立即添加到父级。现在,因为它被添加到树中,所以有另一个引用指向它,因为它是场景的children
数组的一部分。然后你再次实例化一个 Line 变量,所以现在它显示在内存中不同的
SKShapeNode
上(但旧的SKShapeNode
仍在树中)。这个新的 SKShapeNode 没有添加到树中,它的父属性是 nil。因此,您可以将它再次添加到树中,而无需编译器对您大喊大叫。
编辑:
要回应您关于如何更改 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