使用所需的 init(nscoder) 时从代码设置物理体
setting up physics body from code when using required init(nscoder)
我正在尝试利用 init?(coder aDecoder: NSCoder) 函数,以便我可以在我的 sks 文件中子类化精灵。
我可以在 sks 文件中设置物理体,但它不适用于我正在使用的也有圆角的矩形精灵。由于圆角,在使用 init 函数之前,我在代码中设置了 physicsbody,并将宽度设置为略小于正方形的宽度(这样当我的英雄滑出正方形时,没有间隙圆角是..
我知道我可以使用 alpha mask physics body 来获得相同的效果,除了这个,当我的英雄在方块上时似乎有 1 px'ish 的差距,看起来并不不错。
想知道为什么我不能设置物理体,以及我如何做或绕过它?
感谢您的帮助!!!
更新:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
if let p = userData?.value(forKey: "col") as? String {
setup(p)
print("working")
}
}
func setup(_ col: String) {
setupPhysics()
//allSprites.append(self)
在 setupPhysics 中我有:
override func setupPhysics() {
physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: frame.width - 4, height: frame.height - 1))
...more code...
}
这是我的精灵代码,我在 sks 文件中正确设置了它...
我注释掉了 allSprites 的附加部分,这样我就可以证明它不起作用。取消注释后,精灵被添加到 allSprites,然后在我的场景文件中的 didMove 函数中,它循环遍历 allSprites 并运行 setupPhysics():
func setup(_ col: String) {
//setupPhysics()
allSprites.append(self)
// scene file
func setupAllSpritesPhysics() {
for sprite in allSprites { sprite.setupPhysics() }
}
@Knight0fDragon :
您提到这是一个丑陋的修复程序。我不同意它不会以 'correct' 方式工作的事实。目前我没有足够的精灵来导致场景加载出现任何延迟。如果是这样的话,我可以在将来研究一下。
我承认我没有尝试过你提到的方法,因为我不想为我创建的每个精灵创建一个子节点来解决这个问题,即使它有效。尽管如此,我还是很感激你的建议。
为了使它与 SKS 文件一起工作,我将添加一个 child SKNode,其尺寸为您想要的 body,然后在自定义 class 代码中,执行
required init(coder aDecoder:NSCoder){
super.init(coder:aDecoder)
if let child = childNode(withName:"child"), let physicsBody = child.physicsBody{
self.physicsBody = physicsBody
child.removeFromParent()
}
}
我们在这里所做的是将物理 body 从 child 转移到 parent,然后关闭 child。这使我们的代码更加动态,并使设计与功能分开。
好吧,来自 apple 的漂亮小虫子。
发生的事情是 physicsWorld 在 NSCoder 发生时不存在,而不是将物理 body 附加到精灵 body 到世界中,当它确实存在时,它决定缓存位于 SKS 文件中的那个,这就是它不起作用的原因。
因此,解决此问题的一个非常方便的方法是实现一个 worldNode(无论如何,这样做是一种很好的做法,特别是如果你想创建一个暂停屏幕),只需将其删除,然后再将其添加回去在场景加载期间:
class GameScene: SKScene,SKPhysicsContactDelegate {
lazy var worldNode : SKNode = { self.childNode(withName:"//worldNode")!}()
override func sceneDidLoad() {
worldNode.removeFromParent()
addChild(worldNode)
}
}
我正在尝试利用 init?(coder aDecoder: NSCoder) 函数,以便我可以在我的 sks 文件中子类化精灵。
我可以在 sks 文件中设置物理体,但它不适用于我正在使用的也有圆角的矩形精灵。由于圆角,在使用 init 函数之前,我在代码中设置了 physicsbody,并将宽度设置为略小于正方形的宽度(这样当我的英雄滑出正方形时,没有间隙圆角是..
我知道我可以使用 alpha mask physics body 来获得相同的效果,除了这个,当我的英雄在方块上时似乎有 1 px'ish 的差距,看起来并不不错。
想知道为什么我不能设置物理体,以及我如何做或绕过它?
感谢您的帮助!!!
更新:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
if let p = userData?.value(forKey: "col") as? String {
setup(p)
print("working")
}
}
func setup(_ col: String) {
setupPhysics()
//allSprites.append(self)
在 setupPhysics 中我有:
override func setupPhysics() {
physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: frame.width - 4, height: frame.height - 1))
...more code...
}
这是我的精灵代码,我在 sks 文件中正确设置了它...
我注释掉了 allSprites 的附加部分,这样我就可以证明它不起作用。取消注释后,精灵被添加到 allSprites,然后在我的场景文件中的 didMove 函数中,它循环遍历 allSprites 并运行 setupPhysics():
func setup(_ col: String) {
//setupPhysics()
allSprites.append(self)
// scene file
func setupAllSpritesPhysics() {
for sprite in allSprites { sprite.setupPhysics() }
}
@Knight0fDragon :
您提到这是一个丑陋的修复程序。我不同意它不会以 'correct' 方式工作的事实。目前我没有足够的精灵来导致场景加载出现任何延迟。如果是这样的话,我可以在将来研究一下。
我承认我没有尝试过你提到的方法,因为我不想为我创建的每个精灵创建一个子节点来解决这个问题,即使它有效。尽管如此,我还是很感激你的建议。
为了使它与 SKS 文件一起工作,我将添加一个 child SKNode,其尺寸为您想要的 body,然后在自定义 class 代码中,执行
required init(coder aDecoder:NSCoder){
super.init(coder:aDecoder)
if let child = childNode(withName:"child"), let physicsBody = child.physicsBody{
self.physicsBody = physicsBody
child.removeFromParent()
}
}
我们在这里所做的是将物理 body 从 child 转移到 parent,然后关闭 child。这使我们的代码更加动态,并使设计与功能分开。
好吧,来自 apple 的漂亮小虫子。
发生的事情是 physicsWorld 在 NSCoder 发生时不存在,而不是将物理 body 附加到精灵 body 到世界中,当它确实存在时,它决定缓存位于 SKS 文件中的那个,这就是它不起作用的原因。
因此,解决此问题的一个非常方便的方法是实现一个 worldNode(无论如何,这样做是一种很好的做法,特别是如果你想创建一个暂停屏幕),只需将其删除,然后再将其添加回去在场景加载期间:
class GameScene: SKScene,SKPhysicsContactDelegate {
lazy var worldNode : SKNode = { self.childNode(withName:"//worldNode")!}()
override func sceneDidLoad() {
worldNode.removeFromParent()
addChild(worldNode)
}
}