2

我最近一直在排练 Sprite Kit,遇到了一个非常奇怪的问题。缩放父节点时,通过 SKPhysicsJointPin 连接在一起的主体逐渐分开,然后关节断开。让我给你看图片。

这是正常状态: 这是正常状态

这是放大后的样子: 放大

这是缩小的时候: 缩小

如果你问我如何连接身体:我将棕色棒连接到蓝色节点中心的蓝色节点。任何想法我的问题是什么?

编辑:我最近发现当连接体不是动态时,关节不会断裂,并且一切都按预期工作。因此,例如,如果我使用 [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 的属性,它用作精灵上最右边的边缘点。

4

3 回答 3

3

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

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

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

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

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

于 2014-03-10T20:27:21.090 回答
1

I'm not sure what your code looks like, but I ran into a similar problem, where I had a rope in a platformer game (think super mario), using tile maps and if I added the rope at the beginning of the level everything worked ok and the bond between the joints was holding, but when I placed that rope in the middle or at the end of the level, the joints would become more elastic and the rope would break apart, while at the same time sending the physics world into an endless loop, grinding everything to a halt.

The fix turned out to be simple, as you said the physics world belongs to the scene and only the scene itself and I was adding my rope at a position that was based on the node's position, which actually caused the issue.

When I used

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

the following code to convert the node's position to the scene's coordinates and later used that positionInScene variable to attach the joint to as an anchor like so:

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

everything started working correctly.

So in your case, if you could show the code that you used, maybe we could work out something similar. Hope this helps.

于 2014-03-11T15:13:55.043 回答
1

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

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

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

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

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

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

于 2014-04-04T16:02:44.547 回答