模拟两个 Sprite Kit 节点的万有引力

Posted

技术标签:

【中文标题】模拟两个 Sprite Kit 节点的万有引力【英文标题】:Simulate universal gravitation for two Sprite Kit nodes 【发布时间】:2015-07-19 10:11:11 【问题描述】:

我在 Sprite Kit 中有两个节点,我正在用 Swift 编写。

如何使节点通过重力相互吸引?另外,我将如何使用他们的群众?如果一个物体的质量很大,它应该受到更多的引力。

【问题讨论】:

您应该更新您的问题,以显示迄今为止在解决此问题方面所做的一些努力,并添加其他数据,例如:您使用的 Xcode 版本,您在设备上安装的 ios.. . 这样,你可能会得到一个有用的答案。 *** 不是一个人们为您编写完整解决方案的网站,而是一个人们在您遇到困难时乐于提供帮助的网站。 老实说,原则上这不是一个坏问题,可能对未来的读者有用。它的措辞不是很好,也没有表现出尝试解决问题的努力,但公平地说,模拟这个所需的计算对于那些不熟悉模拟刚体物理的人来说可能是具有挑战性的。 我同意 Epic Byte。这实际上对我很有用。 【参考方案1】:

您可以遍历所有节点并使用万有引力方程的适当比率计算对所有其他节点的冲量。我刚刚写了一个简单的例子来展示这是如何完成的。您可以制作自己的自定义“质量”因子,但我只是使用 Sprite Kit 的。我还添加了一个强度因子来放大冲动。我还假设固定时间步长为 1/60 秒。

class GameScene: SKScene 
    var nodes: [SKShapeNode] = []
    let dt: CGFloat = 1.0/60.0 //Delta time.
    let radiusLowerBound: CGFloat = 1.0 //Minimum radius between nodes check.
    let strength: CGFloat = 10000 //Make gravity less weak and more fun!
    override func didMoveToView(view: SKView) 
        self.physicsWorld.gravity = CGVector()
        for i in 1 ... 50  //Create 50 random nodes.
            let rndRadius = 15 + CGFloat(arc4random_uniform(20))
            let rndPosition = CGPoint(x: CGFloat(arc4random_uniform(UInt32(self.size.width))), y: CGFloat(arc4random_uniform(UInt32(self.size.height))))
            let node = SKShapeNode(circleOfRadius: rndRadius)
            node.position = rndPosition
            node.physicsBody = SKPhysicsBody(circleOfRadius: rndRadius)
            self.addChild(node)
            nodes.append(node)
        
    
    override func update(currentTime: NSTimeInterval) 
        for node1 in nodes 
            for node2 in nodes 
                let m1 = node1.physicsBody!.mass*strength
                let m2 = node2.physicsBody!.mass*strength
                let disp = CGVector(dx: node2.position.x-node1.position.x, dy: node2.position.y-node1.position.y)
                let radius = sqrt(disp.dx*disp.dx+disp.dy*disp.dy)
                if radius < radiusLowerBound  //Radius lower-bound.
                    continue
                
                let force = (m1*m2)/(radius*radius);
                let normal = CGVector(dx: disp.dx/radius, dy: disp.dy/radius)
                let impulse = CGVector(dx: normal.dx*force*dt, dy: normal.dy*force*dt)

                node1.physicsBody!.velocity = CGVector(dx: node1.physicsBody!.velocity.dx + impulse.dx, dy: node1.physicsBody!.velocity.dy + impulse.dy)
            
        
    

您也可以将field nodes 添加到您的物理实体中来模拟效果,而不是手动执行计算。尽管被警告,但在某些 Sprite Kit 版本中,字段节点为 broken。

【讨论】:

正确链接到SKFieldNode

以上是关于模拟两个 Sprite Kit 节点的万有引力的主要内容,如果未能解决你的问题,请参考以下文章

iOS 7 Sprite Kit 更改 SKAction 中的 zPosition

Sprite-Kit:节点不会向左移动

使用 Swift 在 sprite kit 中的多个场景中重用相同的 sprite 节点

如何使用 Sprite Kit 创建具有 3D 效果的戒指?

Sprite kit:删除特定节点而不是所有节点

如何确定节点出现在 sprite kit 中的顺序