Friction in Spritekit

Friction in SpriteKit

Here's an example of how to move a sprite based on touch. This approach uses the velocity property of the physics body to move the sprite, so it will interact appropriately with other physics bodies in the scene and be affected by damping, friction, etc.

First, define the scale and damping properties. The scale controls the rate at which the circle moves toward the location of the touch. A larger value will move the circle at a faster rate. The damping property is used to slow the sprite when the touch ends. A smaller value will slow the sprite at a faster rate.

let scale:CGFloat = 2.0
let damping:CGFloat = 0.98

var point:CGPoint?

Save the location when a touch begins. The sprite will move toward this location.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {        
if let touch = touches.anyObject() as UITouch? {
let location = touch.locationInNode(self)
point = location
}
}

Update the location when the touch moves

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
if let touch = touches.anyObject() as UITouch? {
let location = touch.locationInNode(self)
point = location
}
}

Reset the touch location when the touch ends

override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
point = nil
}

Move the sprite toward the specified location

func moveNodeToPoint(sprite:SKSpriteNode, point:CGPoint) {
var dx:CGFloat = (point.x - sprite.position.x) * scale
var dy:CGFloat = (point.y - sprite.position.y) * scale
sprite.physicsBody?.velocity = CGVectorMake(dx, dy)
}

This is called before each frame is rendered. It calls the function that updates the location of the sprite if a touch is active, else it slows the sprite over time

override func update(currentTime: CFTimeInterval) {
if (point != nil) {
moveNodeToPoint(firstCircle, point: point!)
}
else {
// This will slow the circle over time when after the touch ends
let dx = firstCircle.physicsBody!.velocity.dx * damping
let dy = firstCircle.physicsBody!.velocity.dy * damping
firstCircle.physicsBody!.velocity = CGVectorMake(dx, dy)
}
}

Sprite Kit (swift) node friction - screen jumping

Mass and damping can be problematic for characters. Here's how I would set up your player dynamics for jumping:

physicsBody = SKPhysicsBody(rectangleOfSize: CGSizeMake(self.size.width, self.size.height))
physicsBody?.dynamic = true
physicsBody?.allowsRotation = false
physicsBody?.restitution = 0.0
physicsBody?.friction = 0.0
physicsBody?.angularDamping = 0.0
physicsBody?.linearDamping = 0.0
physicsBody?.affectedByGravity = true

When the player jumps, apply an impulse to the physicsBody:

physicsBody?.applyImpulse(CGVector(dx: 0.0, dy: 50.0))

SpriteKit linearDamping - maximum?

The Apple doco is simply wrong.

Just to answer my own question, in iOS:

The actual documentation:

This property is used to simulate fluid or air friction forces on the body. The property must be a value between 0.0 and 1.0. The default value is 0.1. If the value is 0.0, no linear damping is applied to the object.

is simply wrong.

A value of about 10 to 15 is typical when you want typical "strong damping" like in many physics scenes.

I very often use values of 2 or 3. And "10" is our value for "very thick honey".

SpriteKit node going through wall

I think in general you're probably expecting too much. SpriteKit is a game engine, designed to give qualitatively reasonable behavior for scenarios involving normal-ish sorts of physics. It's not a high-precision physics simulation, and when you push it into a region where it's got to do something extreme, it's probably going to fail.

In this case, you're expecting it to simulate a huge number of perfectly elastic collisions within a small amount of time and distance (many collisions per animation frame of the simulation as the heavy block mashes the light one into a tiny gap). It's going to find the first collision in the frame, figure the impulses to apply to the blocks, and then advance to the next frame, with the effect that the big block happily mashes into the space where the small one resides. All the subsequent collisions that would prevent that are being missed in search of 60 fps.



Related Topics



Leave a reply



Submit