How to Apply Impulse to The Node on Touch Angle

Spritekit: Applying Angular Impulse to all surrounding node of exploding node

This approach is not a real-world explosion simulation but can help you as an idea.

Sample Image

I'm making actions like this on each touched node:

node.run(SKAction.sequence([
SKAction.fadeOut(withDuration: 0.0),
SKAction.scale(to: 10, duration: 0.1),
SKAction.removeFromParent()
]))

You can get this example here: https://github.com/Maetschl/SpriteKitExamples/blob/master/BoxWithBalls/BoxWithBalls/GameScene.swift

applyImpulse towards CGPoint SpriteKit

Look up the shooting projectiles section in the tutorial by Ray Wenderlich here:

http://www.raywenderlich.com/42699/spritekit-tutorial-for-beginners

Change the code from the tutorial as follows:

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

// 1 - Choose one of the touches to work with
UITouch * touch = [touches anyObject];
CGPoint location = [touch locationInNode:self];

// 2 - Set up initial location of projectile
SKSpriteNode * projectile = [self childNodeWithName:@"desirednode"];
//make projectile point to your desired node.

// 3- Determine offset of location to projectile
CGPoint offset = rwSub(location, projectile.position);

// 4 - Bail out if you are shooting down or backwards. You can ignore this if required.
if (offset.x <= 0) return;

// 5 - OK to add now - we've double checked position
[self addChild:projectile];

// 6 - Get the direction of where to shoot
CGPoint direction = rwNormalize(offset);

// 7 - Make it shoot far enough to be guaranteed off screen
float forceValue = 200; //Edit this value to get the desired force.
CGPoint shootAmount = rwMult(direction, forceValue);

//8 - Convert the point to a vector
CGVector impulseVector = CGVectorMake(shootAmount.x, shootAmount.y);
//This vector is the impulse you are looking for.

//9 - Apply impulse to node.
[projectile.physicsBody applyImpulse:impulseVector];

}

The projectile object in the code represents your node. Also, you will need to edit the forceValue to get the desired impulse.

Sprite Kit - Apply Impulse to shoot projectile at character

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)

Node rotation doesn't follow a finger

If you want to rotate the sprite towards to touch location, it should be simple as :

    let touchLocation = touch.locationInNode(self)

var dx = hero.position.x - positionInScene.x;
var dy = hero.position.y - positionInScene.y ;

var angle = atan2(dy,dx) + CGFloat(M_PI_2)

hero.zRotation = angle

It worked when I tried, so it can give you an basic idea where to start. Or I misunderstood what you are trying to achieve...

EDIT:

Currently what you will get if you try to convert angle to degrees is angle in range from -90 to 270 degrees. Its described here why. If you want to work with angle in range of 0 to 360, you can change to code above to:

    var dx = missile.position.x - positionInScene.x ;
var dy = missile.position.y - positionInScene.y;

var angleInRadians = atan2(dy,dx) + CGFloat(M_PI_2)

if(angleInRadians < 0){
angleInRadians = angleInRadians + 2 * CGFloat(M_PI)
}

missile.zRotation = angleInRadians

var degrees = angleInRadians < 0 ? angleInRadians * 57.29577951 + 360 : angleInRadians * 57.29577951

Here is the result with debugging data:

Sample Image



Related Topics



Leave a reply



Submit