有没有一种简单的方法可以暂时禁用 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.physicsBodynil 以打开/关闭对象的物理。我个人会避免在这里继承子类,但 YMMV。

【讨论】:

以上是关于有没有一种简单的方法可以暂时禁用 Swift 中精灵的物理体? (雪碧套件)的主要内容,如果未能解决你的问题,请参考以下文章

是否有可能暂时禁用Laravel中的事件?

iPhone - 暂时禁用键盘

我可以暂时禁用Arduino串行数据接收吗?

我似乎没有找到 App Transport Security,所以我可以暂时禁用它

在 Swift 项目中为生产禁用 NSLog

暂时禁用 CSS 过渡效果最干净的方法是啥?