【问题标题】:Sprite kit: remove specific node instead of all nodesSprite kit:删除特定节点而不是所有节点
【发布时间】:2014-02-19 10:53:38
【问题描述】:

我创建了一个应用程序,它具有从天而降的“石头”节点的恒定流,有两种不同的大小。玩家控制第三个石头对象并根据收集到的两种落石类型中的哪一种获得分数。最后,光束对象充当移动地面。 到目前为止,我已经在我的应用程序中添加了碰撞检测,它可以检测不同石头和光束之间的碰撞。这是我的碰撞代码:

static const uint32_t stoneCategory = 1;
static const uint32_t beamCategory = 2;
static const uint32_t stoneCategory2 = 4;

-(void)didBeginContact:(SKPhysicsContact *)contact{

SKPhysicsBody *firstBody;
SKPhysicsBody *secondBody;

CGPoint contactPoint = contact.contactPoint;

float contact_x = contactPoint.x;
float contact_y = contactPoint.y;

if (contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask)
{
     firstBody = contact.bodyA;
     secondBody = contact.bodyB;
}

else
{
    firstBody = contact.bodyB;
    secondBody = contact.bodyA;
}


// First condition: make big stone stick to moving beams 
if ((firstBody.categoryBitMask & stoneCategory) != 0)
{
    SKPhysicsJointFixed *joint =
    [SKPhysicsJointFixed jointWithBodyA:contact.bodyA
                                  bodyB:contact.bodyB
                                 anchor:CGPointMake(contact_x, contact_y)];

    [self.physicsWorld addJoint:joint];
}


// Second condition: remove small stone on collision with big stone

if ((firstBody.categoryBitMask & stoneCategory) != 0 &&
    (secondBody.categoryBitMask & stoneCategory2) != 0)
{

      NSLog(@"Hit");

      [self enumerateChildNodesWithName:@"stone" usingBlock:^(SKNode *node, BOOL *stop) {
      [node removeFromParent];
  }];
}

这完全符合预期。当大石头击中一个光束物体时,它会粘在它上面并随之移动。此外,当大石头和小石头发生碰撞时,小石头就会从场景中移除。 然而:虽然我知道这正是我的代码应该做的,因为它指向我的石头方法(称为“石头”),但在石头之间发生碰撞时,我只希望移除一个特定的小石头,而不是所有的那一刻现场可见的小石头。

我不知道如何做到这一点。回顾一下:我怎样才能删除一个特定的节点,而不是删除它的整个方法?希望我的问题很清楚,如果需要,我很乐意提供更多详细信息。

我的石头方法:

-(void) addStone
 {

 SKSpriteNode *stone = [[SKSpriteNode alloc] initWithColor:[SKColor grayColor] size:CGSizeMake(12, 12)];

stone.position = CGPointMake(skRand(0, self.size.width), self.size.height+12);
stone.name = @"stone";
stone.physicsBody.categoryBitMask = stoneCategory2;
stone.physicsBody.contactTestBitMask = stoneCategory;

stone.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:stone.size];
stone.physicsBody.usesPreciseCollisionDetection = YES;

[self addChild:stone];
}

在我的 createSceneContents 中

SKAction *makeStone= [SKAction sequence:@[
                                        [SKAction performSelector:@selector(addStone) onTarget:self],
                                        [SKAction waitForDuration:0.30 withRange:0.25]
                                        ]];

 [self runAction:[SKAction repeatActionForever:makeStone]];

以上是我的小石头方法。对于大的,我使用了一种类似的方法,但使用了其他名称。

【问题讨论】:

    标签: ios sprite-kit


    【解决方案1】:

    背后的原因 1)sprite 以 z 顺序绘制新对象,然后碰撞也会按照您的绘制顺序发生

    so when you remove a small stone at first time and recreate it changes its body from A to B
    

    只需检查下面联系代码上的特定体型

     if(([contact.bodyA.node.name isEqualToString:@"bigstone"] && [contact.bodyB.node.name isEqualToString:@"smallstone"] ) || ([contact.bodyA.node.name isEqualToString:@"smallstone"] && [contact.bodyB.node.name isEqualToString:@"bigstone"]) )
            {
    
    
                if([contact.bodyA.node.name isEqualToString:@"smallstone"] )
                {
                    [contact.bodyA.node removeFromParent];
                }else{
                    [contact.bodyB.node removeFromParent];
                }
    
        }
    

    【讨论】:

      【解决方案2】:

      试试这行代码

      [self enumerateChildNodesWithName:@"stone" usingBlock:^(SKNode *node, BOOL *stop) {
                  [node removeFromParent];
              }];
      

      【讨论】:

        【解决方案3】:
        if ((firstBody.categoryBitMask & stoneCategory) != 0 &&
            (secondBody.categoryBitMask & stoneCategory2) != 0)
        {
              NSLog(@"Hit");
              [secondBody.node removeFromParent];
        }
        

        【讨论】:

        • 谢谢,但是,我已经尝试过了,结果,这也从场景中移除了光束对象(我认为这是我第一个条件下的第一个物体),而不是只移除那个特定的结石。我说得对吗?
        • 那你应该删除secondBody.node 我想。查看编辑后的答案
        • 我会再试一次,虽然我也试过了,结果它在与光束碰撞时也移除了石头。是否可以添加thirdBody.node?或者不干扰其他条件的东西?
        • 不,这不可能.. 看来我误解了你。你想去除哪块石头?我以为你想删除碰撞的那个
        • 是的,没错。当一块小石头和一块大石头发生碰撞时,我想要移除那个特定的小石头。通过将语句更改为“firstBody.node”,它还会删除其他对象,而不仅仅是小石头
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-08-19
        • 2015-09-18
        • 2014-04-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多