2014-02-19 41 views
2

最近我一直在排练Sprite Kit,我遇到了一个很奇怪的问题。当缩放父节点(改变缩放比例)时,由SKPhysicsJointPin连接在一起的物体逐渐彼此分开,然后关节断开。让我给你看看这些图像。缩放时接头断裂

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

这里放大时'S: 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

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

  1. 规模场景本身,而不是子节点:当我试了一下,不出意外我有一个非常大的问题。由于场景通常是游戏中所有节点的根节点,这意味着所有事情都会相应地放大或缩小。这也包括控制权。所以,不是一个好主意

  2. 您可以尝试子类SKNode,以便它实现自己的SKPhysicsWrold实例并将所有内容添加到该世界:不幸的是,出于某些原因,苹果公司不可能拥有自己的物理世界。是的,你可以将你的关节添加到你想要的任何世界。但关节需要身体共享同一个世界。从纯粹的解开Box2D我记得身体还需要添加到物理世界。所以我假设,苹果已经做到了这一点,当你设置物理体时,它会被添加到scene.physicsWorld中。如果你尝试关节添加到自定义创建的物理世界,你会得到一个Box2D的错误,指出联合能力小于关节计数。 :))

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

    因此,在网络上搜索了20多天并没有找到真正的工作解决方案,我可以说这是一个真正的问题,我认为苹果需要考虑重新考虑,或至少提供良好的解决方案。

1

我不知道你的代码是什么样子,但是我碰到了类似的问题,在那里我一个成熟的游戏有绳(觉得超级马里奥),使用瓷砖地图,如果我说的绳子在水平开始时一切正常,关节之间的连接处于持续状态,但当我将绳子放在中间或水平末端时,关节会变得更有弹性,绳子会分开,而在同时把物理世界变成一个无限循环,把一切都停下来。

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

当我用

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

下面的代码到节点的位置转换到场景的坐标,后来使用了positionInScene变量联合重视像这样一个锚:

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

一切开始正常工作。

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

+0

谢谢@Andrew的洞察力。我已经添加了一些代码。 –

+0

您是否在设置锚点位置时尝试使用[yourScene convertPoint:fromNode:]? – Andrew

+0

我刚刚做了你的建议后,其实我可能以前试过。但它并没有帮助 –

1

遇到与平移世界类似的问题。

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

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

我重写了applyForce:atPoint:和applyTorque:atPoint:来抽象并确保代码保持清晰。

我还发现,如果您在didBeginContact中添加对象(例如爆炸的弹片),则创建的任何对象都必须在绝对物理世界坐标系中给出坐标,而不是相对平移/放大的世界。

在效果上都表现得如同PhysicsWorld是绝对&不变的坐标系中,而SKNode观点正是,对物理世界的看法,并且可以平移等 那里得到令人困惑的是,坐标是大多数情况下透明地从一个系统转换到另一个系统,但并非总是如此。

+0

感谢,对于输入,但我已经意识到,Sprite Kit仍然不成熟,有很多错误/意图行为,从而无法制作出尖端游戏。所以我回到了古老的Cocos2D。 V3现在已经将物理整合到了它中 –