缩放时关节中断

时间:2014-02-19 19:25:27

标签: physics sprite-kit zooming revolute-joints

我最近一直在排练Sprite Kit,我遇到了一个非常奇怪的问题。当缩放(改变比例)父节点时,由SKPhysicsJointPin连接在一起的主体逐渐彼此分离,然后关节断开。让我告诉你这些图片。

这是正常状态: Here's the normal state

这是放大时的情况: Zoomed in

这是缩小时的情况: Zoomed out

如果你问我如何加入尸体:我将棕色棍子连接到蓝色节点中心的蓝色节点上。任何想法我的问题是什么?

编辑:我最近发现,当连接体不是动态的时,关节不会断裂,一切都按预期工作。所以例如,如果我使用[SKPhysicsBody bodyWithEdgleLoopF​​romRect]而不是 [SKPhysicsBody bodyWithRectangleOfSize]为精灵创建物理体,没有问题。但我需要身体充满活力。

这是我用来将物理连接到节点的代码。当然,这一切都是动态完成的。我只是为了简洁而硬编码。

 -(void)attachPhysics{
    //fixedComponentLeft & fixedComponentRight are two SKSprites
    fixedComponentLeft.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:fixedComponentLeft.frame.size.width];
    fixedComponentRight.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:fixedComponentLeft.size.width];
    beam1.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:beam1.size];
    joiningBody.physicsBody=[SKPhysicsBody bodyWithCircleOfRadius:joiningBody1.size.width];
    [self.scene.physicsWorld addJoint:[SKPhysicsJointPin jointWithBodyA:fixedComponentLeft.physicsBody bodyB:beam1.physicsBody anchor:fixedComponentLeft.position]];
    [self.scene.physicsWorld addJoint:[SKPhysicsJointPin  jointWithBodyA:joiningBody.physicsBody bodyB:beam1.physicsBody anchor:beam1.endPoint]];
    beam2.physicsBody=[SKPhysicsBody bodyWithRectangleOfSize:beam2.size];
    [self.scene.physicsWorld addJoint:[SKPhysicsJointPin  jointWithBodyA:joiningBody.physicsBody bodyB:beam2.physicsBody anchor:beam2.position]];
    [self.scene.physicsWorld addJoint:[SKPhysicsJointPin jointWithBodyA:fixedComponentRight.physicsBody bodyB:beam2.physicsBody anchor:beam2.endPoint]];
 }

在上面的代码中,beam1和beam2是SKSpriteNode的子类的实例。默认情况下,锚点是(0,0.5)并且我添加了一个名为endPoint的属性,它作为精灵上最右边的边缘点。

3 个答案:

答案 0 :(得分:3)

事实上,这不是一个答案,但我认为我不会使用评论区域,因为问题很大,不适应那里。我应该猜测问题是由于绘制元素的节点和添加了它们的物体的物理世界具有不同的坐标系。这是因为物理世界属于场景,这意味着无论有多少个子节点被添加到场景中,通常只有一个物理世界,所有连接到不同子节点上不同节点的实体共享同一个世界。我不知道这是好还是坏。以下是我们可以尝试的事情:

  1. 缩放场景本身而不是子节点:当我尝试它时,毫不奇怪我有一个非常大的问题。由于场景通常是游戏中所有节点的根节点,这意味着所有节点都将相应地按比例放大或缩小。这包括控制hud。所以,不是一个好主意

  2. 您可以尝试子类化SKNode,以便它实现自己的SKPhysicsWrold实例并将所有内容添加到该世界:不幸的是,由于某些原因,Apple使得无法拥有自己的物理世界。是的,您可以将关节添加到您想要的任何世界。但关节需要身体来共享同一个世界。从纯粹的,未包装的Box2D我记得身体也需要添加到物理世界。所以我假设,苹果已经自动完成,当你设置物理体时,它会被添加到scene.physicsWorld中。如果您尝试将关节添加到自定义创建的物理世界中,您将得到一个Box2D错误,指出关节容量小于关节计数。 :))

  3. 唯一现实的方法似乎是重建物理身体和关节。但这是一个真正的痛苦,我也没有成功。除了潜在的性能影响之外,这种方法还需要非常精确的身体和关节重建顺序,设置其先前的速度等。

    所以,在网上搜索了20多天而没有找到真正有用的解决方案我可以说这是一个真正的问题,我认为Apple需要考虑重新访问,或者至少提供良好的解决方案。

答案 1 :(得分:1)

我不确定你的代码是什么样的,但我遇到了类似的问题,我在平台游戏中有一根绳子(想想超级马里奥),使用瓷砖地图,如果我在水平的开始一切正常,关节之间的粘合是持有的,但当我将绳子放在水平的中间或末端时,关节会变得更有弹性,绳子会分开,同时把物理世界变成无限循环的时间,把一切都搞定了。

修复结果很简单,正如你所说,物理世界属于场景,只有场景本身,而我正在将绳索添加到基于节点位置的位置,这实际上导致了这个问题。

当我使用

 CGPoint positionInScene = [self convertPoint:nodeB.position  fromNode:self.map];

以下代码将节点的位置转换为场景的坐标,然后使用该positionInScene变量将关节附加到锚点,如下所示:

[SKPhysicsJointFixed jointWithBodyA: nodeA.physicsBody
                              bodyB: nodeB.physicsBody
                             anchor: CGPointMake(positionInScene.x, positionInScene.y)];

一切都正常开始。

因此,在您的情况下,如果您可以显示您使用的代码,也许我们可以找出类似的东西。 希望这会有所帮助。

答案 2 :(得分:1)

在平移世界遇到类似问题。

世界坐标不再与物理坐标相匹配。

所以你必须使用[scene convertPoint:pt fromNode:pannedWorld]的调用。

我已覆盖applyForce:atPoint:和applyTorque:atPoint:抽象并确保代码保持清晰。

我还发现,如果在didBeginContact中添加对象到场景中(例如爆炸的弹片),那么创建的任何对象都需要在绝对物理世界坐标系中给出坐标,而不是相对平移/缩放世界。

实际上,一切都表现得好像PhysicsWorld是绝对的&不可变坐标系,而SKNode视图就是这样,对物理世界的看法,可以平移等等。 令人困惑的是,坐标在大多数情况下透明地从一个系统转换到另一个系统,但并非总是如此。