SpriteKit侧滚动不更新physicsWorld

按照这里的例子(目标C除外)和标准的苹果文档,我发现当myWorld更新它的位置时, physicsWorld不会更新它的位置。 我打开我的skView showsPhysics来validation这一点。 看这些截图。

任何议案之前: 屏幕1 一点点动议之后 屏幕2 走得更远一点 屏幕3 就在联系之前 屏幕4

这是我的myWorld中心代码。 大部分的长度是由于我在处理边缘限制时非常冗长。

 - (void)centerOnNode:(SKNode *)monkeyNode { CGPoint monkeyPosition = monkeyNode.position; // Check if monkey died if (monkeyPosition.y < myWorld.frame.origin.y - sceneHeight/2) { [self monkeyDied]; } // Check if monkey won if (monkeyPosition.x > skyFarRightSide.x) { [self monkeyWon:monkeyNode]; } // Define limits CGFloat scrollTopLimit = skyFarTopSide.y - sceneHeight/2; CGFloat scrollBottomLimit = 0; CGFloat scrollLeftLimit = 0; CGFloat scrollRightLimit = skyFarRightSide.x - sceneWidth/2; // Normal (no limits hit) scrolling if (monkeyPosition.x > scrollLeftLimit && monkeyPosition.x < scrollRightLimit && monkeyPosition.y > scrollBottomLimit && monkeyPosition.y < scrollTopLimit) { [myWorld setPosition:CGPointMake(-monkeyPosition.x, -monkeyPosition.y)]; } // At far left scrolling if (monkeyPosition.x < scrollLeftLimit) { // No y limits hit if (monkeyPosition.y > scrollBottomLimit && monkeyPosition.y < scrollTopLimit) { [myWorld setPosition:CGPointMake(0, -monkeyPosition.y)]; } // Bottom limit hit if (monkeyPosition.y < scrollBottomLimit) { [myWorld setPosition:CGPointMake(0, 0)]; } // Top limit hit if (monkeyPosition.y > scrollTopLimit) { [myWorld setPosition:CGPointMake(0, -scrollTopLimit)]; } } // At far right scrolling if (monkeyPosition.x > scrollRightLimit) { // No y limits hit if (monkeyPosition.y > scrollBottomLimit && monkeyPosition.y < scrollTopLimit) { [myWorld setPosition:CGPointMake(-scrollRightLimit, -monkeyPosition.y)]; } // Bottom limit hit if (monkeyPosition.y < scrollBottomLimit) { [myWorld setPosition:CGPointMake(-scrollRightLimit, 0)]; } // Top limit hit if (monkeyPosition.y > scrollTopLimit) { [myWorld setPosition:CGPointMake(-scrollRightLimit, -scrollTopLimit)]; } } // At far bottom scrolling if (monkeyPosition.y < scrollBottomLimit) { // No x limits hit if (monkeyPosition.x > scrollLeftLimit && monkeyPosition.x < scrollRightLimit) { [myWorld setPosition:CGPointMake(-monkeyPosition.x, 0)]; } // Left limit hit if (monkeyPosition.x < scrollLeftLimit) { [myWorld setPosition:CGPointMake(0, 0)]; } // Right limit hit if (monkeyPosition.x > scrollRightLimit) { [myWorld setPosition:CGPointMake(-scrollRightLimit, 0)]; } } // At far top scrolling if (monkeyPosition.y > scrollTopLimit) { // No x limits hit if (monkeyPosition.x > scrollLeftLimit && monkeyPosition.x < scrollRightLimit) { [myWorld setPosition:CGPointMake(-monkeyPosition.x, -scrollTopLimit)]; } // Left limit hit if (monkeyPosition.x < scrollLeftLimit) { [myWorld setPosition:CGPointMake(0, -scrollTopLimit)]; } // Right limit hit if (monkeyPosition.x > scrollRightLimit) { [myWorld setPosition:CGPointMake(-scrollRightLimit, -scrollTopLimit)]; } } } 

有没有一个优雅的方式来解决这个问题? 到目前为止,我唯一的想法是在centerOnNode中包含更多的代码,以重置myWorld中每个physicsBody的位置。

我注意到,一旦这只猴子接触到了,所有的物理机构都会回到正确的位置。 但是,一个关节anchorPoint结束了错误的地方。

我在GameScene.m中添加了以下便捷方法。

 -(CGPoint)convertSceneToFrameCoordinates:(CGPoint)scenePoint { CGFloat xDiff = myWorld.position.x - self.position.x; CGFloat yDiff = myWorld.position.y - self.position.y; return CGPointMake(scenePoint.x + self.frame.size.width/2 + xDiff, scenePoint.y + self.frame.size.height/2 + yDiff); } 

我使用这种方法来添加关节。 它处理所有需要处理的坐标系转换,导致在这个问题中提出的问题。 例如,我添加关节的方式

  CGPoint convertedRopePosition = [self convertSceneToFrameCoordinates:ropePhysicsBody.node.position]; SKPhysicsJointPin *jointPin = [SKPhysicsJointPin jointWithBodyA:monkeyPhysicsBody bodyB:ropePhysicsBody anchor:convertedRopePosition]; jointPin.upperAngleLimit = M_PI/4; jointPin.shouldEnableLimits = YES; [self.scene.physicsWorld addJoint:jointPin]; 

我不知道过去两年有什么变化,但是这里的其他答案已经不再适用了。 相反,现在我将绳索段的位置与其父母(完整的绳索)相结合。 所以我只是做

 CGPoint convertedRopePosition = CGPointMake(ropePhysicsBody.node.parent.position.x + ropePhysicsBody.node.position.x, ropePhysicsBody.node.parent.position.y + ropePhysicsBody.node.position.y); SKPhysicsJointPin *jointPin = [SKPhysicsJointPin jointWithBodyA:monkeyPhysicsBody bodyB:ropePhysicsBody anchor:convertedRopePosition]; 

这是因为绳段被放置在绳索的全长下,所以它的位置是相对于完整的绳索而不是现场。