有没有一种简单的方法可以暂时禁用 Swift 中精灵的物理体? (雪碧套件)
Posted
技术标签:
【中文标题】有没有一种简单的方法可以暂时禁用 Swift 中精灵的物理体? (雪碧套件)【英文标题】:Is there a simple way to temporarily disable the physics bodies for a sprite in Swift? (SpriteKit) 【发布时间】:2019-12-05 23:54:56 【问题描述】:我正在制作一个迷宫应用程序,它会在完成一个迷宫后生成一个新迷宫。显然,我可以通过执行我在代码wall[location].isHidden = true
中所做的操作来使墙壁(每个墙壁都有自己的物理和精灵存储在数组上的位置)不可见,但我找不到对物理身体绑定在墙上,创造了一个无形的墙。有没有一种简单的方法可以做到这一点而不将其设置为 nil?
澄清一下,并不是我不希望它是动态的,我只是希望在解决迷宫时整个事情都不存在。 另外,我不想将它设置为 nil 的唯一原因是因为我不知道如何以简单的方式恢复它的旧物理体。
【问题讨论】:
【参考方案1】:首选方法是从节点树中物理移除墙。这将提高性能,因为系统不必检查不必要的节点。
只要确保您的墙在移除时被保留,以便您可以在需要时阅读它。
wall[location].removeFromParent()
...
scene.addChild(wall[location])
【讨论】:
这正是我想要的,可惜我已经完成了任务。【参考方案2】:当然
刚刚设置
isDynamic = false
wall.physicsBody?.collisionBitMask = 0
wall.physicsBody?.contactTestBitMask = 0
这几乎将 SKPhysicsBody 与系统的其余部分隔离开来。你有任何 SKJoints 连接到你的身体节点吗?如果你这样做,这可能会很尴尬。
或者你可以将它设置为 nil
wall.physicsBody? = nil
然后在你准备好的时候再做一个方法来设置它
func addPhysics()
wall.physicsBody = SKPhysicsBody(circleOfRadius: 5)
wall.isDynamic = true
wall.physicsBody?.collisionBitMask = whatever
wall.physicsBody?.collisionBitMask = whatever
wall.physicsBody?.contactTestBitMask = whatever
如果您确实设置为 nil 然后恢复它,请确保您在游戏循环的开始或结束时执行此操作。
在 gameScene 中的任一覆盖方法中
override func update(_ currentTime: TimeInterval)
override func didFinishUpdate()
希望对你有帮助
【讨论】:
我想避免使用我在其他地方找到的“nil”选项,因为由于我的做法,将物理重置到我的墙壁上会非常困难。如果可行,我将尝试另一种方法并将其标记为“答案”。 在尝试了你的方法后,很遗憾没有奏效。仅供参考,根本没有发生碰撞,只是让我的玩家立方体撞到墙上而不是移动。 在没有找到其他方法后,我使用了你描述的“nil”,它有效,只是很多额外的代码。 出于兴趣,为什么仅仅禁用physicsBody的碰撞和接触还不够? 我猜他正在调整墙壁纹理的大小,当他完成时,物理体不再匹配形状。 ?不知道真的只是猜测【参考方案3】:您已经有了答案,但另一种方法可能是使用一个名为 inactivePhysicsBody
(或类似)的额外属性(即“SKPhysicsBody”)对 SKSpriteNode 进行子类化。
当您想“关闭”该节点的物理特性时,请将inactivePhysicsBody
属性设置为physicsBody
,然后将physicsBody
设置为nil
。然后,您可以在必要时轻松恢复物理体。
或者你可以在新类中添加方法来做同样的事情:
wall.activatePhysicsBody()
wall.inactPhysicsBody()
【讨论】:
嗯 - 这行不通,对吧,因为 PB 仍然存在;它只是不会连接到墙上。您可以扩展子类中的方法,以将不活动的 PB “移动”到安全位置或禁用碰撞和接触。 取决于您何时删除它。只要它不在物理阶段,这应该有效。身体是相对于节点的,所以没有节点,身体就不会出现在场景中。 另外,不需要子类。使用扩展 + userData【参考方案4】:给拥有精灵的对象一个对精灵物理体的“额外”引用,例如:
init(sprite: SKSpriteNode)
self.sprite = sprite
self.physicsBody = sprite.physicsBody
super.init()
然后您可以将self.sprite.physicsBody
设置为self.physicsBody
或nil
以打开/关闭对象的物理。我个人会避免在这里继承子类,但 YMMV。
【讨论】:
以上是关于有没有一种简单的方法可以暂时禁用 Swift 中精灵的物理体? (雪碧套件)的主要内容,如果未能解决你的问题,请参考以下文章