0

是否有可能在空间发生碰撞之前取消它?

示例:A 和 B 即将发生碰撞,但 A 具有一个属性,因此对于特定的 SKPhysicsContact,不应发生与 B 的碰撞。空间中的所有其他碰撞应该不受影响。

在阅读 Apple 的课程文档时,它说:

在物理模拟步骤期间调用物理接触委托方法。在此期间,无法修改物理世界,并且在模拟中对物理实体的任何更改的行为都是未定义的。如果您需要进行此类更改,请在 didBegin( :) 或 didEnd( :) 中设置一个标志,并在 SKSceneDelegate 的 update(_:for:) 方法中响应该标志进行更改。

这是否意味着我可以在实际碰撞成为事实之前检测到didBegin()中的状态并在update ()中更改碰撞掩码?

有一个类似主题的旧线程:SpriteKit SKPhysicsBody 在一个方向上碰撞,就像一扇门,你只能通过但不能返回

4

2 回答 2

1

当然

您可以将contactBitMask 设置为在检测到联系人时调用didBegin 方法。一旦调用了 didBegin 并且您从 (_contact: SKPhysicsContact) 参数中的信息中识别出您想要的节点。

设置一个标志,指示已发生联系。从那里运行一个流控制 (if) 语句override func didFinishUpdate()来检查标志的值。如果为 true,则更改对象的碰撞掩码。

然后在下一个游戏循环迭代中,物理不会检测到碰撞。尽管在检测到接触的游戏循环中,您仍然会遇到初始碰撞。不过有办法解决这个问题。就像在碰撞发生之前制造第二个更大的物理体来检测接触。

于 2019-12-09T14:26:32.467 回答
0

根据我的理解,您希望一个对象有时会穿过一个对象。

以下代码应该可以工作:

enum CategoryBitMasks{
  case player1Collidable = 1 << 0
  case player2Collidable = 1 << 1
  case player1 = 1 << 2
  case player2 = 1 << 3
  case oneTimePass = 1 << 4
  case unstoppable = 1 << 5
  case player = CategoryBitMasks.player1 | CategoryBitMasks.player2
  case playerCollidable = CategoryBitMasks.player1Collidable | CategoryBitMasks.player2Collidable
}


//Create an obstacle with category (.player1Collidable | .player2Collidable)
//                   with contact 0
//                   with collision 0
//Create a player with category (.player1 | .unstoppable)
//                with contact .player1Collidable
//                with collision .player1Collidable 

func didBeginContact(contact: SKPhysicsContact) {
    var obstacle = contact.bodyA.categoryBitMask >= contact.bodyB.categoryBitMask ?contact.bodyA, contact.bodyB
    var player = contact.bodyB == obstacle ? contact.bodyA, contact.bodyB

    //Only allows the player to pass through 1 object
    if player.categoryBitMask || CategoryBitMasks.oneTimePass && obstacle.categoryBitMask || CategoryBitMasks.playerCollidable  {
       obstacle.categoryBitMask &= ~(player.collisionBitMask & CategoryBitMasks.playerCollidable) //turns player1Collidable off
       player.categoryBitMask &= ~(player.categoryBitMask & CategoryBitMasks.oneTimePass) //turns oneTimePass off

    }

    //Allows player to pass through all objects
    if player.categoryBitMask || CategoryBitMasks.unstoppable && obstacle.categoryBitMask || CategoryBitMasks.playerCollidable  {

       //This will bypass all objects providing their collision is not set to the player
       player.collisionBitMask &= ~(player.collisionBitMask & CategoryBitMasks.playerCollidable) //turns player1Collidable off

       //This will bypass all objects, but is dangerous because the category is now changed, meaning if a contact does happen, .player can't be used
       //player.categoryBitMask &= ~(player.categoryBitMask & CategoryBitMasks.player ) //turns player1Collidable off

    }
}

记得在需要时重置面具

这将允许玩家 1 根据您给它的类别穿过对象,同时强制玩家 2 仍然被同一个对象阻挡。

希望这些示例将帮助您调整游戏的需求。

于 2019-12-09T17:50:37.353 回答