Does anyone have any idea how I can make my SKSpriteNode
defy gravity? I thought of inverting the default gravity but realise I also need things to fall too!
It seems like it should be easy but reading through the documentation I can’t see how I would do it!
Thanks
Update: In iOS 8 / OS X Yosemite (10.10), physics fields provide an elegant solution to these sorts of problems. Here's a quick take on using them to add buoyancy (for a specific set of nodes) to your scene.
SKFieldNode
with the linearGravityFieldWithVector
constructor, providing a vector that's the opposite of gravity, and add the field node to your scene.fieldBitMask
on your balloons to something unique.categoryBitMask
on the field to something that overlaps with the balloons' fieldBitMask
, but that does not overlap with the fieldBitMask
of any other bodies.Now, the balloons will rise or hold steady, but other objects will fall. Tweaking the field's strength
will let you tune whether the balloons' buoyancy is perfectly balancing gravity (so that they float in place, but are disturbed when touched), or slightly more or less than gravity (so that they slowly rise or fall).
By default, a field is infinite, covering the whole scene, but you can change that with the field's region
property to limit it to a portion of the scene. (This is useful if you want to simulate buoyancy in water — once an object rises past the top of the field at the water's surface, it falls back in.)
Also, if you want variable buoyancy as per @TheisEgeberg's answer, you can control its variation over distance with the falloff
property.
In iOS 7 / OS X Mavericks (10.9), or if you want more precise control over which forces apply where and when, you can use the approach from my original answer below.
If you want an object to really float like a balloon — that is, to be buoyant, affected by gravity but also counteracting it — you'll need to apply a force to it on every frame (i.e. in your update:
method).
Beware scaling: gravity is a constant acceleration, but if you're applying a force to counteract gravity, a force is proportional to mass. To make a vector that perfectly balances gravity for use in applyForce:
, you'll need to:
{-1,-1,-1}
to point in the opposite directionmass
of the body you're applying the force to (F = ma
, where gravity or anti-gravity is a
).150
— there's a bug where the SKPhysicsWorld.gravity
property isn't in the same units as applyForce:
. (If you turn SKPhysicsWorld
gravity off and use SKFieldNode
gravity instead, you don't need to do this.)Unlike turning off affectedByGravity
and applying an action to make the balloon rise, this approach works well with the rest of the physics sim. With a balancing force exactly equal to gravity, the balloon will float in place — after colliding with other things it'll return to equilibrium. If the balancing force is greater than gravity, the balloon will rise, but its rise will be hindered by other bodies in its way.
First off, an SKSpriteNode
isn't affected by gravity at all. It is the SKPhysicsBody
that belongs to the node that is affected by gravity.
Second...
myNode.physicsBody.afectedByGravity = NO;
:D
If you want it to rise upwards then you can add an action to it...
SKAction *moveAction = [SKAction moveByX:0 y:-10 duration:1];
SKAction *repeatingAction = [SKAction repeatActionForever:moveAction];
[myNode runAction:repeatingAction];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With