我的目标是使firstBody以恒定的速度(在本例中为500)处于“轨道” firstBody。
基于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的速度正在放缓。你会发现,我设置各式各样的东西像gravity
上SKPhysicsWorld
,friction
linearDamping
与angularDamping
上SKPhysicsBody
和frictionTorque
上SKPhysicsJoint
。
那么,我在做什么错呢?以及如何在不进行可怕的计算的情况下保持secondNode的速度恒定-update
?
另外-我知道我可以添加SKAction来遵循循环路径,但是在这种情况下,这不是一个合理的解决方案。
如果我缺少一些简单的东西,也可以建议删除我设置的“ 0”和“ false”中的哪一个。
谢谢
当与物理引擎打交道时,通常会放慢行为。它们并不完美,尤其是在约束等更复杂的场景中。您不应该依赖Sprite
Kit提供完美的连续运动仿真,因为我们不知道物理引擎在引擎盖下做什么。涉及的因素太多。
在需要连续运动的情况下(尤其是恒定的向心运动),最好总是自己计算并保存这些值。对于这种行为,在update方法中根本没有逃脱编写计算的麻烦。
因此,我写了一个快速的示例项目,计算出绕特定点运行所需的必要速度。您只需指定周期,轨道位置和轨道半径。请注意,由于我正在计算所有内容,因此不需要任何内容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图像。注意,因为它是完全动态的,所以实际上我们可以在向心点旋转时移动它。
If however you really want to use your currentSKJoints
implementation for
some reason then I have another solution for you.
Simply keep updating your
node’s linear velocity so that it never slows down.
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))
}
}
Regardless of the solution you pick (and once again I highly recommend the
first solution!), you can choose to apply the velocity over time rather than
instantaneously for a more realistic effect. I talk more about this in my
answer here
Hopefully I have provided you with enough information to resolve your issue.
Let me know if you have any questions. And best of luck with your game!
我正在尝试使用LibGDX CatmullRomSpline在路径上实现恒定速度,但在使其工作时遇到了问题。我曾多次尝试研究这个话题,包括阅读LibGDX维基,但他们对实现恒定速度的解释没有真正意义,我无法让他们的方法发挥作用。https://github.com/libgdx/libgdx/wiki/Path-interface- 在我的例子中,我有几个与球的速度一致的视觉辅助工具,屏幕底部的条
问题内容: 我已经在这个问题上进行了很多搜索,但是我找不到真正合适的答案。 我需要围绕给定点(例如0,0,0)旋转圆柱体,但是默认情况下会给出圆柱体的枢轴。我该如何改变? 为了更好地说明我想做什么,我将显示3张图像。 imageshack.us/photo/my-images/259/aintgood.jpg imageshack.us/photo/my-images/840/whatineed.
问题内容: 我试图在这个问题中创建一个类似于“奖杯轮”的可旋转节点。到目前为止,我具有甩尾功能,可以使用效果很好的UIPanGestureRecognizer在物理物体上添加角度脉冲。我也可以通过触摸停止旋转。 现在,我试图通过拖动或滑动手势来微调方向盘,这样,如果玩家对最终的效果不满意,就可以手动旋转/拖动/旋转它所喜欢的旋转方式。 目前,我将触摸的位置保存在touchesBegan中,并尝试在
问题内容: 我有一个带有多个子SKSpriteNode的SKNode。一个简化的例子: 我想对所有这些孩子采取行动。当我在上执行操作时,没有任何效果。 我不能在父项上使用,因为它的许多子项已经具有我正在使用的名称。 有没有一种方法可以遍历的所有子项,以便对所有子项执行单个操作? 问题答案: 您可以简单地列举: 如有必要,请检查每个孩子是否确实是: 从 Swift 2(Xcode 7)开始, 可以将
下面是java中的一个代码段,用于将坐标为a(10,10),B(20,10),C(20,20),D(10,20)的顶点围绕正方形的中心点旋转一个角度。正方形的边是10分。旋转角度为90度。理想情况下,旋转后A必须变成B,B必须变成C,C必须变成D,D必须变成A。 所取得的结果是不正确的 > 点A(10,10)旋转到(20,10)---正确 点B(20,10)旋转到(30,10)----不正确 nu
我正在使用OpenCV和Python在图像中查找圆。我能够使用OpenCV教程中的Hough圆变换代码找到圆。我想在圆心周围裁剪一个矩形。我没有能够得到正确的裁剪功能,并尝试了多种裁剪组合,要么得到了一个错误或图像的不正确部分。有人能说明我应该如何输入裁剪坐标吗?这就是我一直遇到的错误: 错误:(-215)大小。宽度 谢谢!