【问题标题】:Is it possible to deactivate collisions in physics bodies in spriteKit?是否可以在 spriteKit 中停用物理体中的碰撞?
【发布时间】:2014-01-21 19:44:27
【问题描述】:

我正在寻找在我的 iO 版 spriteKit 游戏中与我的英雄一起收集物品的最佳方法,在尝试了几种方法之后,我的结论是最好的方法是拥有一个带有可以检测到碰撞但不会与我的英雄发生碰撞的实体。有可能做到吗?停用物理体的碰撞而不停用其检测碰撞的能力?我知道听起来有点矛盾......因为,另一种方法是只创建一个没有物理体的 SKSpriteNode,那么就不会有碰撞,但是“检测”碰撞的方法将是手工制作的,而且更难,因为我需要在我的英雄中设置一个坐标系检测,当他处于那些特定坐标(在项目上)时,我会让项目消失。知道如何更轻松地执行这两种方法中的任何一种吗?

【问题讨论】:

  • 这就是类别位掩码
  • 如果您还没有阅读过它们,请转到 sprite kit PG 的 96 页。阅读“碰撞和接触示例:太空中的火箭”
  • 这非常愚蠢,但 Apple 似乎并没有添加一些东西来简单地禁用物理上的物理。这意味着,所有游戏开发的基本技术,使用您克隆的“模型” - 无法在 iOS 中完成。不错。

标签: ios sprite-kit


【解决方案1】:

查看SKPhysicsBody 类中的collisionBitMaskcategoryBitMaskcontactTestBitMask

本质上,具有相同collisionBitMask 值的物理实体将相互“传递”。

  • 更正:如果类别和碰撞位匹配,它们就会相互作用。如果它们不匹配,那么这两者将交互。如果碰撞位和类别位 ,那么该项目当然会与任何东西都没有交互.

然后,您设置categoryBitMaskcontactTestBitMask 值以创建SKPhysicsContact 接触对象。最后,你的 Class 应该采用SKPhysicsContactDelegate 协议。使用- didBeginContact:方法检测和处理SKPhysicsContact对象。

static const uint8_t heroCategory = 1;
static const uint8_t foodCategory = 2;
--
food.physicsBody.categoryBitMask = foodCategory;
food.physicsBody.contactTestBitMask = heroCategory;
food.physicsBody.collisionBitMask = 0;
--
hero.physicsBody.categoryBitMask = heroCategory;
hero.physicsBody.contactTestBitMask = foodCategory;
hero.physicsBody.collisionBitMask = 0;
--
-(void)didBeginContact:(SKPhysicsContact *)contact {
    SKPhysicsBody *firstBody = contact.bodyA;
    SKPhysicsBody *secondBody = contact.bodyB;
}

【讨论】:

  • 这个答案需要更好的澄清,这个例子中的两个对象会互相穿透的原因是因为collisionBitMask = 0这意味着“不要与任何东西碰撞”。如果由于某种原因您希望 2 个相同类型的对象与所有相互咬合的对象发生碰撞,请确保 collisionBitMask 不包含用于 categoryBitMask 的标志
【解决方案2】:

简答:

yourHero.physicsBody.collisionBitMask = 0;

collisionBitMask 的默认值为 0xFFFFFFFF(所有位设置),这就是节点与其他节点发生冲突的原因

【讨论】:

    【解决方案3】:

    您可以通过设置播放器和项目对象的 categoryBitMask 和 contactBitMask 来做到这一点,但请确保您没有设置碰撞位掩码以使两者相互交互(见下文)

    static const int playerCategory = 1;
    static const int worldCategory = 2;
    static const int objectCategory = 4;    
    
    ....
    
    SKSpriteNode *player, *item;
    
    ....
    
    player.physicsBody.categoryBitMask = playerCategory;
    player.physicsBody.collisionBitMask = worldCategory;
    player.physicsBody.contactTestBitMask = worldCategory;
    
    ....
    
    item.physicsBody.categoryBitMask = objectCategory;
    item.physicsBody.contactTestBitMask = playerCategory | worldCategory;
    item.physicsBody.collisionBitMask = worldCategory;
    

    这样,物理体将拾取玩家与世界对象、物品与世界对象之间的碰撞,但不会拾取玩家与物品之间的碰撞。它将触发对 didBeginContact 的调用,您可以在其中删除项目节点、添加健康等。

    希望这会有所帮助!

    【讨论】:

      【解决方案4】:

      contactTestBitMask 用于触发didBeginContactcollisionBitMask 用于激活节点上的物理。

      // add a physics body
      ship.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:ship.size.width/2];
      
      // set the category for ship
      ship.physicsBody.categoryBitMask = shipCategory;
      
      // detect collisions with asteroids and edges
      ship.physicsBody.contactTestBitMask = asteroidCategory | edgeCategory;
      
      // physically collide with asteroids
      ship.physicsBody.collisionBitMask = asteroidCategory;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-10-01
        • 2015-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-26
        相关资源
        最近更新 更多