【问题标题】:How to make a SKSpriteNode react for only certain collisions如何使 SKSpriteNode 仅对某些碰撞做出反应
【发布时间】:2014-01-18 17:39:11
【问题描述】:

在这个项目中,有两个玩家,两个都可以射击。当对面的玩家子弹击中一艘船时,它会降低他们的健康并消失,这很好用。问题是我不希望船只或子弹在相互碰撞时做出反应。

这是制作第一个播放器的代码:

player = [SKSpriteNode spriteNodeWithImageNamed:filePath];
    player.size = CGSizeMake(100, 100);
    player.position = CGPointMake(150, 250);
    player.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:player.size];
    player.physicsBody.categoryBitMask = playerCategory;
    player.physicsBody.collisionBitMask = wallCategory;
    player.physicsBody.friction = 1.0f;
    player.physicsBody.restitution = 1.0f;
    player.physicsBody.linearDamping = 1.0f;
    player.physicsBody.allowsRotation = NO;
    [self addChild:player];

第二个玩家:

playerTwo = [SKSpriteNode spriteNodeWithImageNamed:filePath];
        playerTwo.size = CGSizeMake(100, 100);
        playerTwo.position = CGPointMake((384*2)-150, (512*2)-250);
        playerTwo.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:playerTwo.size];
        playerTwo.physicsBody.categoryBitMask = playerTwoCategory;
        playerTwo.physicsBody.collisionBitMask = wallCategory;
        playerTwo.physicsBody.friction = 1.0f;
        playerTwo.physicsBody.restitution = 1.0f;
        playerTwo.physicsBody.linearDamping = 1.0f;
        playerTwo.physicsBody.allowsRotation = NO;
        [self addChild:playerTwo];

类别的初始化:

static const uint32_t playerCategory = 2;
static const uint32_t playerTwoCategory =   5;
static const uint32_t wallCategory =   1;
static const uint32_t bulletCategory =   4;
static const uint32_t bulletTwoCategory =   7;

玩家一号的子弹制作:

    SKSpriteNode * bullet = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor]     size:CGSizeMake(5, 5)];
    bullet.position =  [gunOne convertPoint:CGPointMake(0,0) toNode:self];
    [self addChild:bullet];
    bullet.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bullet.frame.size];
    bullet.physicsBody.categoryBitMask = bulletCategory;
    bullet.physicsBody.dynamic = YES;
    bullet.physicsBody.contactTestBitMask = playerTwoCategory | wallCategory;
    bullet.physicsBody.collisionBitMask = wallCategory;
    bullet.physicsBody.usesPreciseCollisionDetection = YES;

玩家二的子弹制作:

    SKSpriteNode * bulletTwo = [SKSpriteNode spriteNodeWithColor:[UIColor whiteColor] size:CGSizeMake(5, 5)];
    bulletTwo.position =  [gunOneTwo convertPoint:CGPointMake(0,0) toNode:self];
    [self addChild:bulletTwo];
    bulletTwo.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:bulletTwo.frame.size];
    bulletTwo.physicsBody.categoryBitMask = bulletTwoCategory;
    bulletTwo.physicsBody.dynamic = YES;
    bulletTwo.physicsBody.contactTestBitMask = playerCategory | wallCategory;
    bulletTwo.physicsBody.collisionBitMask = wallCategory;
    bulletTwo.physicsBody.usesPreciseCollisionDetection = YES;

这样做的方式是否有任何明显的问题会导致第一个玩家和子弹对碰撞做出反应?提前感谢您的帮助,很抱歉读了这么久。

【问题讨论】:

    标签: sprite-kit skspritenode skphysicsbody


    【解决方案1】:

    'static const uint32_t' 是问题所在,它们实际上统计了类别的顺序,而不是你必须做的就是将船只估价相同的数量,然后是子弹,它们也必须是相同的数量。要在 didBeginContact 中区分它们,请给每个名称取一个名称并改用它。

    【讨论】:

      【解决方案2】:

      我会像这样定义位和掩码:

      #define BIT_WALL        (0x01 << 0)   // 0000 0001
      #define BIT_PLAYER_1    (0x01 << 1)   // 0000 0010
      #define BIT_PLAYER_2    (0x01 << 2)   // 0000 0100
      #define BIT_BULLET_1    (0x01 << 3)   // 0000 1000
      #define BIT_BULLET_2    (0x01 << 4)   // 0001 0000
      
      // Just Bit groups for players and bullets
      #define MASK_PLAYERS    (BIT_PLAYER_1 | BIT_PLAYER_2)  // 0000 0110
      #define MASK_BULLETS    (BIT_BULLET_1 | BIT_BULLET_2)  // 0001 1000
      
      // Players and bullets collide with wall, but not with each other
      #define COLLISION_MASK_WALL       (MASK_PLAYERS | MASK_BULLETS) 
      #define COLLISION_MASK_PLAYER_1   (BIT_WALL)
      #define COLLISION_MASK_PLAYER_2   (BIT_WALL)
      #define COLLISION_MASK_BULLET_1   (BIT_WALL)
      #define COLLISION_MASK_BULLET_2   (BIT_WALL)
      
      // Contact is detected if anything hits wall, or, if bullet1 hits player2 (and vice versa)
      #define CONTACT_MASK_WALL         (MASK_PLAYERS | MASK_BULLETS)
      #define CONTACT_MASK_PLAYER_1     (BIT_WALL | BIT_BULLET_2)
      #define CONTACT_MASK_PLAYER_2     (BIT_WALL | BIT_BULLET_1)
      #define CONTACT_MASK_BULLET_1     (BIT_WALL | BIT_PLAYER_2)
      #define CONTACT_MASK_BULLET_2     (BIT_WALL | BIT_PLAYER_1)
      
      
      // Creating objects
      {
          wall.physicsBody.categoryBitMask = BIT_WALL;
          wall.physicsBody.collisionBitMask = COLLISION_MASK_WALL;
          wall.physicsBody.contactTestBitMask = CONTACT_MASK_WALL;
      
          player1.physicsBody.categoryBitMask = BIT_PLAYER_1;
          player1.physicsBody.collisionBitMask = COLLISION_MASK_PLAYER_1;
          player1.physicsBody.contactTestBitMask = CONTACT_MASK_PLAYER_1;
      
          bullet1.physicsBody.categoryBitMask = BIT_BULLET_1;
          bullet1.physicsBody.collisionBitMask = COLLISION_MASK_BULLET_1;
          bullet1.physicsBody.contactTestBitMask = CONTACT_MASK_BULLET_1;
      
          player2.physicsBody.categoryBitMask = BIT_PLAYER_2;
          player2.physicsBody.collisionBitMask = COLLISION_MASK_PLAYER_2;
          player2.physicsBody.contactTestBitMask = CONTACT_MASK_PLAYER_2;
      
          bullet2.physicsBody.categoryBitMask = BIT_BULLET_2;
          bullet2.physicsBody.collisionBitMask = COLLISION_MASK_BULLET_2;
          bullet2.physicsBody.contactTestBitMask = CONTACT_MASK_BULLET_2;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多