Applying Impulses in Spritekit

Applying impulses in SpriteKit

I suggest using option three + checking to see if the y velocity is too high, then to lessen or not do the boost at all.

  if starType == .Special  && player.physicsBody?.velocity.dy <= 40 {
//40 is just an example number
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 90.0))
}
else {
player.physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 40.0))
}

You could also change the impulse depending on what the current velocity is. It all depends on what you want the mechanics to be, and what the max velocity should be.

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)

Applying impulse on a SpriteKit node

Some thoughts...

  1. I suggest you use an SKAction or two instead of an NSTimer in Sprite Kit games. SKActions pause/resume appropriately when you pause/resume the scene and/or view
  2. The update method is called ~60 times a second not every second
  3. Checking the status of a jump in update is not need
  4. Alternatively, you can check if the hero is on the ground before starting another jump sequence instead of using a timer. The game may frustrate the user if the hero is on the ground (and ready to jump) but the timer is still counting down

and some code...

if (!jumping) {
jumping = true
let wait = SKAction.waitForDuration(3)
let leap = SKAction.runBlock({
// Play sound and apply impulse to hero
self.jump()
})
let action = SKAction.group([leap, wait])
runAction(action) {
// This runs only after the action has completed
self.jumping = false
}
}

Delay Apply Impulse in SpriteKit

As you already have follow action, you need just to chain it with delay action. There is a class method waitForDuration that allows you to initialize such Action fast.

Here is a code that will do delay and apply impulse afterward:

for touch in (touches as! Set<UITouch>) {
fish.physicsBody?.velocity = (CGVectorMake(0,0))
fisherman.physicsBody?.velocity = (CGVectorMake(0,0))

let delay = SKAction.waitForDuration(2.0)

let fishApplyImpulse = SKAction.applyImpulse(CGVectorMake(0, 1000),
duration sec: 0.0)
let fishActions = SKAction.sequence([delay, fishApplyImpulse])

let fishermanApplyImpulse = SKAction.applyImpulse(CGVectorMake(0, 3000),
duration sec: 0.0)

let fishermanActions = SKAction.sequence([delay, fishermanApplyImpulse])

fish.runAction(fishActions)
fisherman.runAction(fishermanActions)
}

Code uses SKAction additions for applyImpulse available starting from iOS 9.

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

Swift Spritekit apply rotational impulse

Try:

node.physicsBody?.applyAngularImpulse

or:

node.physicsBody?.angularVelocity

applying impulse to SKShapeNode

You're on the right track! All you need to do is add a physics body to your player to make it move.

player.physicsBody = SKPhysicsBody(circleOfRadius: 30) 
// the 30 in this case is an example. You can just change it to whatever you want


Related Topics



Leave a reply



Submit