Search code examples
iosobjective-csprite-kitcollision-detectionskspritenode

creating physics body for a SKSpriteNode in order to detect contact


as the title suggest, i have issue with creating contact between my enemies sprite and the hero laser(bullet). i create my enemies trough the following method and am adding them to the view.

-(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];
    }

}

}

then i add the bullets through a mutable array and then adding my bullets to the enemies sprites as their child. that part works. i can create contact between hero and the enemy bullet and it gets detected. what i have issue with is that my hero's laser does not create contact with the enemy thus i can't make the enemy take hit from the laser. i tries adding the physics body to the method i am using but throws all the other sprites into hell and they don't respond properly anymore.

the following code is my collision code which i am using in update method:

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!");
        }
    }

is there any way that i can use to create a physics body for my enemies so i can create the contact between the hero laser and the enemies sprite with the same structure i have currently ? any help is amazingly appreciated.


Solution

  • You most certainly can create a physics body for your enemies. Right after this code enemy = [SKSpriteNode spriteNodeWithImageNamed:@"enemy_spaceship.png"]; you can add a physics body like this:

    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
    

    There are many ways to create a physics body. You can do a rectangle shape, circle shape, outline a texture or draw your own.

    You should read the Apple docs on this subject to get a better understanding of what you can do and what properties are available.