问题描述
我在 Sprite Kit 中有两个节点,我正在用 Swift 编写.
I have two nodes in Sprite Kit, and I'm writing in Swift.
如何使节点通过重力相互吸引?另外,我将如何使用他们的群众?如果一个物体的质量很大,它应该受到更多的引力.
How would I make the nodes attracted to each other by the force of gravity? Also, how would I use their masses? If an object has a big mass, it should gravitate more.
推荐答案
您可以循环遍历所有节点,并使用万有引力方程的适当比率计算对所有其他节点的冲量.我刚刚写了一个简单的例子来展示这是如何完成的.您可以制作自己的自定义质量"因子,但我只是使用 Sprite Kit 的.我还添加了一个强度因子来放大冲动.我还假设固定时间步长为 1/60 秒.
You can loop through all nodes and calculate the impulse to all other nodes using the appropriate ratios of the universal gravitation equation. I just wrote a quick example showing how this is done. You can make your own custom "mass" factor, however I'm simply using Sprite Kit's. I also added a strength factor to amplify the impulse. I'm also assuming fixed time step of 1/60 seconds.
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)
}
}
}
}
除了手动执行计算,您还可以添加 场节点 到您的物理实体以模拟效果.尽管受到警告,但在某些 Sprite Kit 版本中,字段节点损坏.
Instead of performing the calculation manually you could also add field nodes to your physics bodies to simulate the effect. Although be warned, field nodes are broken in certain versions of Sprite Kit.
这篇关于模拟两个 Sprite Kit 节点的万有引力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!