Search code examples
iosobjective-cxcodesprite-kitskphysicsbody

Sprite Kit - Apply Impulse to shoot projectile at character


I am developing a game using Sprite-Kit (Objective-C). It's a game where you control a bird in flight and arrows and other bad projectiles are shot at you from the right/top/bottom sides of the screen. I am using physics instead of an SKAction in order to accomplish this as I want it to seem as life-like as possible. So I know to use applyImpulse on the projectile to shoot it towards the bird, but what I am wondering is how can gaurantee that the projectile will be shot directly at the bird, no matter the y-positioning of the bird and the y-positioning of the projectile prior to applyImpulse?

I'm having a very frustrating time accomplishing this so any help on this matter would be greatly appreciated. Thanks.


Solution

  • The basic steps are

    1. Calculate vector components from the projectile launcher to the bird
    2. Normalize the components (optional)
    3. Create a vector by scaling the (normalized) components
    4. Apply impulse to the projectile using the vector

    Here's an example of how to do that

    Obj-C

    // Calculate vector components x and y
    CGFloat dx = bird.position.x - launcher.position.x;
    CGFloat dy = bird.position.y - launcher.position.y;
    
    // Normalize the components
    CGFloat magnitude = sqrt(dx*dx+dy*dy);
    dx /= magnitude;
    dy /= magnitude;
    
    // Create a vector in the direction of the bird
    CGVector vector = CGVectorMake(strength*dx, strength*dy);
    
    // Apply impulse
    [projectile.physicsBody applyImpulse:vector];
    

    Swift

    // Calculate vector components x and y
    var dx = bird.position.x - launcher.position.x
    var dy = bird.position.y - launcher.position.y
    
    // Normalize the components
    let magnitude = sqrt(dx*dx+dy*dy)
    dx /= magnitude
    dy /= magnitude
    
    // Create a vector in the direction of the bird
    let vector = CGVector(dx:strength*dx, dy:strength*dy)
    
    // Apply impulse
    projectile.physicsBody?.applyImpulse(vector)