SpriteKit – 制作一个不受重力影响的精灵(就像一个气球)

有没有人有任何想法,我可以让我的SKSpriteNode反抗引力? 我想到了颠倒默认的重力,但意识到我也需要的东西掉下来!

这看起来应该很容易,但通过文档阅读我不明白我会怎么做!

谢谢

更新:在iOS 8 / OS X Yosemite(10.10)中,物理领域为这类问题提供了一个很好的解决scheme。 这里有一个快速的使用它们来为你的场景增加浮力(对于一组特定的节点)。

  1. 使用linearGravityFieldWithVector构造函数创build一个SKFieldNode ,提供与重力相反的vector,并将场节点添加到场景中。
  2. 将气球上的fieldBitMask设置为唯一的东西。
  3. 将字段上的categoryBitMask设置为与气球的fieldBitMask重叠的fieldBitMask ,但不与任何其他主体的fieldBitMask重叠。

现在,气球会上升或保持稳定,但其他物体会下降。 调整场地的strength可以让你调整气球的浮力是否完美平衡重力(使它们漂浮在原地但受到干扰时),或稍微大于或小于重力(使其缓慢上升或下降)。

默认情况下,一个字段是无限的,覆盖整个场景,但是您可以使用字段的region属性更改该字段,以将其限制为场景的一部分。 (如果要模拟水中的浮力,这是非常有用的 – 一旦物体从水面上升到水面上方,就会回落。)

此外,如果你想根据@ TheisEgeberg的答案想要浮力变化,你可以通过falloff属性来控制它在距离上的变化。

在iOS 7 / OS X Mavericks(10.9)中,或者如果您想更精确地控制哪些力适用于何时何地,可以使用下面我原始答案中的方法。


如果你想要一个物体像一个气球一样漂浮 – 也就是浮力,受到重力的影响,但也会抵消它 – 你需要在每一帧(即在你的update:方法)上施加一个力。

当心比例缩放:重力是一个恒定的加速度,但是如果你正在施加一个力来抵消重力,一个力与质量成正比。 要制作一个完美平衡重力的vector,以便在applyForce:使用,您需要:

  1. 通过{-1,-1,-1}来缩放重力vector以指向相反的方向
  2. F = ma ,其中重力或反重力是a )的大小。
  3. 规模SKPhysicsWorld.gravity 150 – 有一个错误,其中SKPhysicsWorld.gravity属性是不是在applyForce:相同的单位。 (如果您closuresSKPhysicsWorld重力并使用SKFieldNode重力,则不需要这样做。)

与closuresaffectedByGravity和应用动作来使气球上升不同,这种方法与物理模拟的其余部分很好的结合。 在平衡力与重力完全相等的情况下,气球就会漂浮在原地 – 与其他物体碰撞后,气球会恢复平衡。 如果平衡力大于重力,气球就会上升,但其上升会受到其他机构的阻碍。

首先, SKSpriteNode根本不受重力的影响。 属于受重力影响的节点是SKPhysicsBody

第二…

 myNode.physicsBody.afectedByGravity = NO; 

:d

如果你想要它向上升起,那么你可以添加一个动作…

 SKAction *moveAction = [SKAction moveByX:0 y:-10 duration:1]; SKAction *repeatingAction = [SKAction repeatActionForever:moveAction]; [myNode runAction:repeatingAction]; 

正如很多人所说的那样,这是关于反作用力的

所以是的,你可以对气球施加反作用力,使其向上。

但为了让它看起来像一个气球,你需要了解是什么使气球上升:气压。 由于您使用的氦气或其他轻气体比空气轻,因此会开始上升,换句话说,较重的空气会进入气球下方。 它就像一块木头在水中,更重的水将在木材下面,直到木材被浸泡,甚至比水更重。

所以你应该做的是使反作用力适应气球的高度,越高压力就越小。 这是一种模拟浮力的方法。

这是我的答案:

 - (MyClass *)newRisingObject { MyClass *risingObject = [MyClass spriteNodeWithImageNamed:@"image"]; [risingObject setPosition:CGPointMake(CGRectGetMidX(self.frame), CGRectGetMinY(self.frame))]; [risingObject setName:@"name"]; [risingObject setUserInteractionEnabled:YES]; // Physics // [risingObject setPhysicsBody:[SKPhysicsBody bodyWithCircleOfRadius:risingObject.size.width / 2.0f]]; [risingObject.physicsBody setRestitution:1.0f]; [risingObject.physicsBody setFriction:0.0f]; [risingObject.physicsBody setLinearDamping:0.0f]; [risingObject.physicsBody setAngularDamping:0.0f]; [risingObject.physicsBody setMass:1.3e-6f]; return risingObject; } 

 - (void)didMoveToView:(SKView *)view { /* Setup your scene here */ MyClass *risingObject = [self newRisingObject]; [self addChild:risingObject]; } 

 - (void)update:(CFTimeInterval)currentTime { /* Called before each frame is rendered */ [self enumerateChildNodesWithName:@"name" usingBlock:^(SKNode *node, BOOL *stop) { // Push object up // [node.physicsBody applyImpulse:CGVectorMake(0.0f, node.physicsBody.mass * OBJECT_ACCELERATION)]; }]; }