- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我的目标是让 secondBody 以恒定速度(在本例中为 500)“绕”firstBody。
基于 Constant movement in SpriteKit我已经实现了以下内容:
override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector(dx: 0, dy: 0)
let firstNode = SKShapeNode(circleOfRadius: 10)
addChild(firstNode)
firstNode.position = CGPointMake(CGRectGetWidth(frame) / 2.0, CGRectGetHeight(frame) / 2.0)
let firstPhysicsBody = SKPhysicsBody(circleOfRadius: 10)
firstPhysicsBody.dynamic = false
firstNode.physicsBody = firstPhysicsBody
let secondNode = SKShapeNode(circleOfRadius: 10)
addChild(secondNode)
secondNode.position = CGPointMake(CGRectGetWidth(frame) / 2.0 + 40, CGRectGetHeight(frame) / 2.0 + 40)
let secondPhysicsBody = SKPhysicsBody(circleOfRadius: 10)
secondPhysicsBody.friction = 0
secondPhysicsBody.linearDamping = 0
secondPhysicsBody.angularDamping = 0
secondPhysicsBody.affectedByGravity = false
secondNode.physicsBody = secondPhysicsBody
let joint = SKPhysicsJointPin.jointWithBodyA(firstPhysicsBody, bodyB: secondPhysicsBody, anchor: firstNode.position)
joint.frictionTorque = 0
physicsWorld.addJoint(joint)
secondPhysicsBody.velocity = CGVector(dx: 0, dy: 500)
}
我遇到的问题是随着时间的推移,secondNode 正在变慢。你会注意到我在 SKPhysicsWorld
上设置了各种各样的东西,比如 gravity
,friction
linearDamping
&
和 SKPhysicsBody
上的 angularDampingSKPhysicsJoint
上的 frictionTorque
。
那么,我做错了什么?我如何才能保持 secondNode 的速度不变而不在 -update
中进行可怕的计算?
另外 - 我知道我可以添加一个 SKAction 来遵循循环路径,但在这种情况下这不是一个合理的解决方案。
如果我遗漏了一些简单的东西,你能否也建议我设置的'0'和'false'中的哪些可以删除。
谢谢
最佳答案
在处理物理引擎时,通常会出现减速行为。它们并不完美,尤其是在约束等更复杂的场景中。你不应该依赖 Sprite Kit 来提供完美的连续运动模拟,因为我们不知道物理引擎在幕后做了什么;涉及的因素太多了。
在需要连续运动的情况下(尤其是像恒定的向心运动),最好自己计算并保存这些值。对于这样的行为,您的更新方法中根本没有逃避写入计算。
因此我编写了一个快速示例项目来计算绕特定点运行所需的必要速度。您只需指定一个周期、轨道位置和轨道半径。请注意,因为我正在计算所有内容,所以不需要任何 SKJoints
,因此这也使该实现更加轻量级。我强烈建议你以这种方式绕轨道运行,因为它可以让你完全控制你希望节点如何相互绕轨道运行(即你可以让节点绕轨道移动节点,你可以有椭圆轨道路径,你可以在关键期间调整轨道游戏中的时刻等)
import SpriteKit
class GameScene: SKScene {
var node1: SKShapeNode!
var node2: SKShapeNode!
var node2AngularDistance: CGFloat = 0
override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector(dx: 0, dy: 0)
node1 = SKShapeNode(circleOfRadius: 10)
node1.position = CGPoint(x: self.size.width/2.0, y: self.size.height/2.0)
node1.physicsBody = SKPhysicsBody(circleOfRadius: 10)
node2 = SKShapeNode(circleOfRadius: 10)
node2.position = CGPoint(x: self.size.width/2.0+50, y: self.size.height/2.0)
node2.physicsBody = SKPhysicsBody(circleOfRadius: 10)
self.addChild(node1)
self.addChild(node2)
}
override func update(currentTime: NSTimeInterval) {
let dt: CGFloat = 1.0/60.0 //Delta Time
let period: CGFloat = 3 //Number of seconds it takes to complete 1 orbit.
let orbitPosition = node1.position //Point to orbit.
let orbitRadius = CGPoint(x: 50, y: 50) //Radius of orbit.
let normal = CGVector(dx:orbitPosition.x + CGFloat(cos(self.node2AngularDistance))*orbitRadius.x ,dy:orbitPosition.y + CGFloat(sin(self.node2AngularDistance))*orbitRadius.y);
self.node2AngularDistance += (CGFloat(M_PI)*2.0)/period*dt;
if (fabs(self.node2AngularDistance)>CGFloat(M_PI)*2)
{
self.node2AngularDistance = 0
}
node2.physicsBody!.velocity = CGVector(dx:(normal.dx-node2.position.x)/dt ,dy:(normal.dy-node2.position.y)/dt);
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
node1.position = (touches.first! as! UITouch).locationInNode(self)
}
}
下面是一个显示向心运动的 gif。请注意,因为它是完全动态的,我们实际上可以在它绕轨道运行时移动向心点。
如果您出于某种原因真的想使用当前的 SKJoints
实现,那么我为您提供了另一种解决方案。只需不断更新节点的线速度,这样它就不会减速。
override func update(currentTime: NSTimeInterval) {
let magnitude = sqrt(secondNode.physicsBody!.velocity.dx*secondNode.physicsBody!.velocity.dx+secondNode.physicsBody!.velocity.dy*secondNode.physicsBody!.velocity.dy)
let angle = Float(atan2(secondNode.physicsBody!.velocity.dy, secondNode.physicsBody!.velocity.dx))
if magnitude < 500 {
secondNode.physicsBody!.velocity = CGVector(dx: CGFloat(cosf(angle)*500), dy: CGFloat(sinf(angle)*500))
}
}
无论您选择哪种解决方案(我再次强烈推荐第一种解决方案!),您都可以选择随时间而不是瞬间应用速度以获得更逼真的效果。我在回答 here 中对此进行了更多讨论
希望我已经为您提供了足够的信息来解决您的问题。如果您有任何问题,请告诉我。祝您游戏顺利!
关于swift - 使用 SKNode 绕点恒速运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28786940/
我是一名优秀的程序员,十分优秀!