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
- Calculate vector components from the projectile launcher to the bird
- Normalize the components (optional)
- Create a vector by scaling the (normalized) components
- 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...
- I suggest you use an
SKAction
or two instead of anNSTimer
in Sprite Kit games.SKAction
s pause/resume appropriately when you pause/resume the scene and/or view - The
update
method is called ~60 times a second not every second - Checking the status of a jump in
update
is not need - 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.
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
Swift Getnameinfo Unreliable Results for Ipv6
What Is The Advantage of Closure Stored Property Initialisation
Create Custom Action in a Class for Use in Interface Builder
Load a Spritekit Scene from Another Bundle
My UIcollectionview Does Not Scroll Smoothly Using Swift
Implement a Crosshair Kind Behaviour in Realitykit
Alamofire Request Not Working in Swift 4 Project
How to Disable a Button of a Nstoolbar of Macos X in Swift
How to Replace My .Xib File with Pure Swift 3
Why Cannot Read The Receipt Data for On-Device Validation
How to Use Nscalendar Range Function Within Calendar
Uitextfield with a Placeholder Containing an Image and Text
How to Save Text Field Value in UIcollectionviewcell
User Specific Avatar in Jsqmessagesviewcontroller with Sdwebimage
How to Draw a Hollow Circle with Two Different Colors