SpriteKit - 制作精灵无视重力(如气球)

时间:2014-06-05 15:08:45

标签: ios sprite-kit

有没有人知道如何让SKSpriteNode无视重力?我想过要反转默认的引力,但意识到我也需要掉下来的东西!

看起来应该很容易但是阅读文档后我看不出我会怎么做!

由于

4 个答案:

答案 0 :(得分:11)

更新:在iOS 8 / OS X Yosemite(10.10)中,物理领域为这些问题提供了一个优雅的解决方案。这里可以快速使用它们为场景添加浮力(针对特定的节点集)。

  1. 使用linearGravityFieldWithVector构造函数创建SKFieldNode,提供与重力相反的向量,并将字段节点添加到场景中。
  2. 将气球上的fieldBitMask设置为唯一的。
  3. 将字段上的categoryBitMask设置为与气球“fieldBitMask重叠的内容,但不会与任何其他实体的fieldBitMask重叠。”
  4. 现在,气球会上升或保持稳定,但其他物体会下降。调整场地的strength将让你调整气球的浮力是否完全平衡重力(使它们漂浮在原位,但在触摸时受到干扰),或稍微多于或少于重力(以便它们缓慢上升或落)。

    默认情况下,字段是无限的,覆盖整个场景,但您可以使用字段的region属性更改该字段,以将其限制为场景的一部分。 (如果你想模拟水中的浮力,这很有用 - 一旦一个物体越过水面上的水面顶部,就会重新进入水中。)

    此外,如果您想要根据@TheisEgeberg's answer获得可变浮力,则可以使用falloff属性控制距离的变化。

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


    如果你想让一个物体像气球一样漂浮 - 也就是说,要浮力,受到重力的影响而且还要抵消它 - 你需要在每一帧上施加一个力(即你的{{1方法)。

    注意缩放:重力是一个恒定的加速度,但如果你施加一个力来抵抗重力,力就会与质量成正比。要制作一个完美平衡重力的矢量,以便在update:中使用,您需要:

    1. 将重力矢量按applyForce:缩放以指向相反的方向
    2. 按照您施加力的身体的{-1,-1,-1}缩放(mass,重力或反重力为F = ma)。
    3. a缩放 - 有一个错误,150属性与SKPhysicsWorld.gravity的单位不同。 (如果您关闭applyForce:重力并改为使用SKPhysicsWorld重力,则无需执行此操作。)
    4. 与关闭SKFieldNode并应用动作使气球上升不同,此方法适用于物理模拟的其余部分。当平衡力与重力完全相等时,气球将浮动到位 - 在与其他物体碰撞后,它将恢复平衡。如果平衡力大于重力,气球将上升,但其上升将受到其他物体的阻碍。

答案 1 :(得分:2)

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

其次...

myNode.physicsBody.afectedByGravity = NO;

:d

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

SKAction *moveAction = [SKAction moveByX:0 y:-10 duration:1];

SKAction *repeatingAction = [SKAction repeatActionForever:moveAction];

[myNode runAction:repeatingAction];

答案 2 :(得分:1)

正如许多人所说,这是关于反力量的。

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

但为了使它看起来像一个气球,你需要了解气球上升的原因:气压。由于您使用的氦气或任何轻质气体比空气轻,它会开始上升,换句话说,较重的空气会进入气球下方。它就像一块木头在水中,较重的水会流到木头下面,直到木头被浸湿,甚至比水还重。

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

答案 3 :(得分:1)

这是我的答案:

- (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)];
    }];
}