swift – 使用SKNode在点周围进行恒速轨道运动

swift – 使用SKNode在点周围进行恒速轨道运动,第1张

概述我的目标是以恒定速度(在这种情况下为500)使第二个“轨道”第一个体. 基于Constant movement in SpriteKit,我实现了以下内容: override func didMoveToView(view: SKView) { physicsWorld.gravity = CGVector(dx: 0, dy: 0) let firstNode = SKSha 我的目标是以恒定速度(在这种情况下为500)使第二个“轨道”第一个体.

基于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,摩擦lineardamPing& amp; SKPhysicsBody上的angulardamPing和SKPhysicsJoint上的frictionTorque.

那么,我做错了什么?如果不在-update中进行可怕的计算,我如何保持secondNode的速度不变?

另外 – 我知道我可以添加一个SKAction来遵循循循环径,但在这种情况下这不是一个合理的解决方案.

如果有一些我遗漏的简单内容,你是否也可以建议删除我所设置的’0’和’false’中的哪一个.

谢谢

解决方法 在处理物理引擎时,通常会出现减速行为.它们并不完美,尤其是在诸如约束等更复杂的场景中.你不应该依赖Sprite Kit来提供完美的连续运动模拟,因为我们不知道物理引擎在引擎盖下做了什么.涉及的因素很多.

在需要连续运动的情况下(尤其是恒定的向心运动),最好自己计算和保存这些值.对于像这样的行为,在更新方法中根本没有转义写入计算.

所以我写了一个快速示例项目,计算绕特定点轨道运行所需的速度.您只需指定一个周期,轨道位置和轨道半径.请注意,因为我正在计算所有内容,所以不需要任何SKJoints,因此这使得该实现也更加轻量级.我强烈建议你以这种方式进行轨道运行,因为它可以让你完全控制你的节点如何相互绕轨道运行(即你可以让节点绕轨道运动节点,你可以有椭圆轨道,你可以在关键时调整轨道你游戏中的时刻等)

import SpriteKitclass 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在点周围进行恒速轨道运动全部内容,希望文章能够帮你解决swift – 使用SKNode在点周围进行恒速轨道运动所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://www.outofmemory.cn/web/1019562.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-23
下一篇 2022-05-23

发表评论

登录后才能评论

评论列表(0条)

保存