【问题标题】:SpriteKit: How to simulate magnetic forceSpriteKit:如何模拟磁力
【发布时间】:2014-02-23 17:07:54
【问题描述】:

我正在使用 iOS SpriteKit 开发游戏。我试图在这个游戏中制作一个物体,它会将物体拉向它,并且随着物体靠近它,力会变得更大,想想磁铁或黑洞。我一直很难弄清楚要更改哪些属性以使此节点物理体在它们经过时吸引其他节点。

【问题讨论】:

  • 不能用简单的属性来完成。您必须计算对象与吸引子之间的距离,并根据对象与吸引子的距离和吸引子的假定重量向吸引子施加冲量。如果您想要全面的重力模拟(每个物体也是一个吸引子),这可能会变得非常昂贵,因为计算的数量会随着物体的数量呈指数增长。

标签: ios7 sprite-kit game-physics


【解决方案1】:

在 iOS 8 和 OS X 10.10 中,SpriteKit 有 SKFieldNode 用于创建作用于区域内的物体的力。这对于浮力、面积比重和“磁铁”等事物非常有用。

不过,请注意——您从该课程中获得的 magneticField 可能不是您想要的那种“磁铁”游戏玩法。磁场的行为符合real-world physics at the micro level...,也就是说,它偏转移动的带电物体。我们通常认为的磁铁——粘在冰箱上、捡起报废汽车或让悬浮滑板飞起来的那种——就是这种力量的a higher-level effect

如果您想要一个能吸引附近任何东西(或某些特定事物)的领域,radialGravityField 就是您真正想要的。 (为了只吸引特定的东西,在场上使用categoryBitMask,在它应该/不应该与之交互的身体上使用fieldBitMask。)

如果您想要一个或多或少强烈吸引不同事物的领域,或者吸引某些事物而排斥其他事物,electricField 是一个不错的选择。您可以使用物理实体的charge 属性使其受到场的吸引或排斥(负值或正值)或或多或少的强烈影响(绝对值大或小)。


在 iOS 8 和 OS X 10.10 之前,SpriteKit 的物理模拟不包括此类力。

不过,这并不妨碍您自己进行模拟。在场景的update: 方法中,您可以找到物体之间的距离,计算每个物体上与该距离成比例的力(以及与您正在模拟的任何磁场强度),然后对每个物体施加力。

【讨论】:

  • 谢谢,这是有道理的。有什么例子可以做到这一点?
  • 太好了,感谢您的帮助,这应该可以让我解决这个问题!
【解决方案2】:

是的,您可以在精灵套件中创建磁力

-(void)didSimulatePhysics
{
  [self updateCoin];
}

-(void) updateCoin
{
    [self enumerateChildNodesWithName:@"coin" usingBlock:^(SKNode *node, BOOL *stop) {
        CGPoint position;
        position=node.position;
        //move coin right to left
        position.x -= 10;
        node.position = position;
        //apply the magnetic force between hero and coin
        [self applyMagnetForce:coin];
        if (node.position.x <- 100)
            [node removeFromParent];

    }];
}

-(void)applyMagnetForce:(sprite*)node
{
    if( gameViewController.globalStoreClass.magnetStatus)
    {
        //if hero under area of magnetic force
        if(node.position.x<400)
        {
            node.physicsBody.allowsRotation=FALSE;
            ///just for fun
            node.physicsBody.linearDamping=10;
            node.physicsBody.angularVelocity=10*10;
            //where _gameHero is magnet fulling object
            [node.physicsBody applyForce:CGVectorMake((10*10)*(_gameHero.position.x-      node.position.x),(10*10)*(_gameHero.position.y-node.position.y)) atPoint:CGPointMake(_gameHero.position.x,_gameHero.position.y)];

        }
    }
}

记住英雄和硬币体都需要动态

【讨论】:

    【解决方案3】:

    自从 Apple 在 iOS 8 中引入 SKFieldNode 以来,您现在似乎可以了。

    【讨论】:

      【解决方案4】:

      您使用以下代码 sn-ps 来执行您要查找的操作,但它没有 attractionrepulsion 属性

      正文代码:

      let node = SKSpriteNode(imageNamed: "vortex")
                                  node.name = "vortex"
                                  node.position = position
                                  node.run(SKAction.repeatForever(SKAction.rotate(byAngle: CGFloat.pi, duration: 1)))
                                  node.physicsBody = SKPhysicsBody(circleOfRadius: node.size.width / 2)
                                  node.physicsBody?.isDynamic = false
      
                                  node.physicsBody?.categoryBitMask = CollisionTypes.vortex.rawValue
                                  node.physicsBody?.contactTestBitMask = CollisionTypes.player.rawValue
                                  node.physicsBody?.collisionBitMask = 0
                                  addChild(node)
      

      与那个黑洞体接触后:

      func playerCollided(with node: SKNode) {
              if node.name == "vortex" {
                  player.physicsBody?.isDynamic = false
                  isGameOver = true
                  score -= 1
      
                  let move = SKAction.move(to: node.position, duration: 0.25)
                  let scale = SKAction.scale(to: 0.0001, duration: 0.25)
                  let remove = SKAction.removeFromParent()
                  let sequence = SKAction.sequence([move, scale, remove])
      
                  player.run(sequence) { [unowned self] in
                      self.createPlayer()
                      self.isGameOver = false
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-05-24
        • 2017-08-05
        • 2014-06-13
        相关资源
        最近更新 更多