【问题标题】:creating physics body for a SKSpriteNode in order to detect contact为 SKSpriteNode 创建物理体以检测接触
【发布时间】:2015-03-28 15:22:16
【问题描述】:

正如标题所示,我在创建敌人精灵和英雄激光(子弹)之间的接触时遇到了问题。我通过以下方法创建我的敌人并将它们添加到视图中。

-(void)Enemies{
//not always come
int GoOrNot = [self getRandomNumberBetween:0 to:1];

if(GoOrNot == 1){

    SKSpriteNode *enemy;

    int randomEnemy = [self getRandomNumberBetween:0 to:1];
    if(randomEnemy == 0)
        enemy = [SKSpriteNode spriteNodeWithImageNamed:@"enemy_spaceship.png"];
    else
        enemy = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship15.png"];


    enemy.scale = 0.4;

    enemy.position = CGPointMake(450, 0);
    enemy.hidden = NO;

    CGPoint location = CGPointMake(450, 320);

    SKAction *moveAction = [SKAction moveTo:location duration:2.5];
    SKAction *doneAction = [SKAction runBlock:(dispatch_block_t)^() {
        //NSLog(@"Animation Completed");
        enemy.hidden = YES;
    }];

    SKAction *moveAsteroidActionWithDone = [SKAction sequence:@[moveAction,doneAction ]];

    [enemy runAction:moveAsteroidActionWithDone withKey:@"asteroidMoving"];
    [self addChild:enemy];

    _enemyBullets = [[NSMutableArray alloc] initWithCapacity:kNumEnemyBullet];
    for (int i = 0; i < kNumEnemyBullet; ++i) {
        SKSpriteNode *enemyBullets = [SKSpriteNode spriteNodeWithImageNamed:@"rocket"];
        enemyBullets.hidden = YES;
        [enemyBullets setXScale:0.5];
        [enemyBullets setYScale:0.5];
        [_enemyBullets addObject:enemyBullets];
        [enemy addChild:enemyBullets];
    }

}

}

然后我通过一个可变数组添加子弹,然后将我的子弹作为他们的孩子添加到敌人的精灵中。那部分有效。我可以在英雄和敌人的子弹之间建立联系并被检测到。我的问题是我的英雄的激光不会与敌人产生接触,因此我无法让敌人受到激光的打击。我尝试将物理体添加到我正在使用的方法中,但将所有其他精灵扔进地狱,它们不再正确响应。

以下代码是我在更新方法中使用的碰撞代码:

for (SKSpriteNode *enemyBullets in _enemyBullets) {
        if (enemyBullets.hidden) {
            continue;
        }
        if ([_ship intersectsNode:enemyBullets]) {
            enemyBullets.hidden = YES;
            SKAction *blink = [SKAction sequence:@[[SKAction fadeOutWithDuration:0.1],
                                                   [SKAction fadeInWithDuration:0.1]]];
            SKAction *blinkForTime = [SKAction repeatAction:blink count:4];
            SKAction *shipExplosionSound = [SKAction playSoundFileNamed:@"explosion_large.caf" waitForCompletion:NO];
            [_ship runAction:[SKAction sequence:@[shipExplosionSound,blinkForTime]]];
            _lives--;
            _livesLabel.text = [NSString stringWithFormat:@"%d Lives", _lives];
            NSLog(@"your ship has been hit!");
        }
    }

有什么方法可以用来为我的敌人创建一个物理体,这样我就可以在英雄激光和具有我目前拥有的相同结构的敌人精灵之间创建接触?非常感谢任何帮助。

【问题讨论】:

    标签: ios objective-c sprite-kit collision-detection skspritenode


    【解决方案1】:

    你当然可以为你的敌人创造一个物理身体。在此代码enemy = [SKSpriteNode spriteNodeWithImageNamed:@"enemy_spaceship.png"]; 之后,您可以像这样添加一个物理体:

    enemy.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:self.size];
    enemy.physicsBody.categoryBitMask = CategoryEnemy; // or whatever you need
    enemy.physicsBody.collisionBitMask = CategoryRock; // or whatever you need
    enemy.physicsBody.contactTestBitMask = CategoryBullet // or whatever you need
    enemy.physicsBody.dynamic = NO; // or YES
    enemy.physicsBody.allowsRotation = NO; // or YES
    enemy.physicsBody.restitution = 0; // or another value between 0 to 1
    enemy.physicsBody.friction = 0.0; // or another value between 0 to 1
    

    有很多方法可以创建物理实体。您可以制作矩形、圆形、勾勒纹理或绘制自己的纹理。

    您应该阅读有关此主题的Apple docs,以更好地了解您可以做什么以及可用的属性。

    【讨论】:

    • 我的问题远没有我想象的那么引人注目。就像有时所有代码一样。有了我的结构,我通过一种方法将游戏开始时的所有内容添加到场景中。我只是从未将敌人添加到该方法中,因此由于该节点显示为零,因此从未发生过碰撞。通过在开始时添加敌人并对我的碰撞代码进行细微修改,我能够解决这个问题。但根据我的问题,你的答案是正确的,我奖励你答案。谢谢你的帮助,虽然我的问题在别处。
    • @XCodeMonkey - 感激不尽。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-14
    • 2013-11-26
    • 2016-06-18
    相关资源
    最近更新 更多