Sprite Kit,删除 Sprite 以进行碰撞

Posted

技术标签:

【中文标题】Sprite Kit,删除 Sprite 以进行碰撞【英文标题】:Sprite Kit, Remove Sprite for collision 【发布时间】:2014-01-22 14:33:02 【问题描述】:

我正在使用 sprite kit 制作游戏,而且我对 ios 编程还很陌生,我一直在努力获得它,所以当 2 张图片发生碰撞时,其中一张会被删除或不可见。我对此非常不成功,想知道是否有人知道该怎么做? 下面是船(它总是停留)和要删除的对象之一。

-(void)addShip

    //initalizing spaceship node
    ship = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
    [ship setScale:0.5];
    ship.zRotation = - M_PI / 2;

    //Adding SpriteKit physicsBody for collision detection
    ship.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:ship.size];
    ship.physicsBody.categoryBitMask = shipCategory;
    ship.physicsBody.dynamic = YES;
    ship.physicsBody.contactTestBitMask = DonutCategory | PizzaCategory | ChocolateCategory | SoftCategory | AppleCategory | GrapeCategory | OrangeCategory | BananaCategory;
    ship.physicsBody.collisionBitMask = 0;
    ship.physicsBody.usesPreciseCollisionDetection = YES;
    ship.name = @"ship";
    ship.position = CGPointMake(260,30);
    actionMoveRight = [SKAction moveByX:-30 y:0 duration:.2];
    actionMoveLeft = [SKAction moveByX:30 y:0 duration:.2];

    [self addChild:ship];


- (void)shoot1 //donut

    // Sprite Kit knows that we are working with images so we don't need to pass the image’s                extension
    Donut = [SKSpriteNode spriteNodeWithImageNamed:@"1"];
    [Donut setScale:0.15];
    // Position the Donut outside the top
    int r = arc4random() % 300;
    Donut.position = CGPointMake(20 + r, self.size.height + Donut.size.height/2);


    Donut.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:Donut.size];
    Donut.physicsBody.categoryBitMask = DonutCategory;
    Donut.physicsBody.dynamic = YES;
    Donut.physicsBody.contactTestBitMask = shipCategory;
    Donut.physicsBody.collisionBitMask = 0;
    Donut.physicsBody.usesPreciseCollisionDetection = YES;

    // Add the Dount to the scene
    [self addChild:Donut];

    // Here is the Magic
    // Run a sequence
    [Donut runAction:[SKAction sequence:@[
    // Move the Dount and Specify the animation time
    [SKAction moveByX:0 y:-(self.size.height + Donut.size.height) duration:5],
    // When the Dount is outside the bottom
    // The Dount will disappear
    [SKAction removeFromParent]]]];

【问题讨论】:

【参考方案1】:

你必须设置你的物理世界的代理:

self.physicsWorld.contactDelegate = self;

然后,当两个对象接触时,您就会调用一个委托:

- (void)didBeginContact:(SKPhysicsContact *)contact 
    SKPhysicsBody *firstBody, *secondBody;

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

    if ((firstBody.categoryBitMask & projectileCategory) != 0 &&
        (secondBody.categoryBitMask & monsterCategory) != 0)
    
        //remove the donut and the target
        SKSpriteNode *firstNode = (SKSpriteNode *) firstBody.node;
        SKSpriteNode *secondNode = (SKSpriteNode *) secondBody.node;
        [firstNode removeFromParent];
        [secondNode removeFromParent];
    

欲了解更多信息,您可以跳转到collision part in this tutorial。

【讨论】:

尝试此操作时出现以下错误 No visible @interface for 'SKPhysicsBody' 声明选择器 'removeFromParent' 知道为什么吗? 我的错误,您必须删除 SKSpriteNode,而不是 Body :)。检查编辑。但是,如果您有任何问题,该教程会显示您想要的示例;)。 为了将来的参考,我建议编辑帖子以区分“碰撞”和“接触”。两者非常不同;你的回答虽然是正确的,虽然我对接触/冲突了如指掌,但在这个意义上有点模棱两可。 @Andriko13 好点了吗?从碰撞变为接触。

以上是关于Sprite Kit,删除 Sprite 以进行碰撞的主要内容,如果未能解决你的问题,请参考以下文章

Sprite kit:删除特定节点而不是所有节点

在 Sprite Kit 中以编程方式发送邮件

以一定速度在屏幕上移动对象。(Sprite Kit)

Sprite Kit:为所有场景只创建一次节点

增加 Sprite Kit 游戏的难度

Sprite Kit 无法通过分数,Null 值