SpriteKit侧滚动不会更新physicsWorld

时间:2015-01-12 04:05:24

标签: ios sprite-kit

按照示例here(目标C除外)和标准Apple文档,我发现physicsWorldmyWorld更新其位置时不会更新其位置。我在我的skView上打开showsPhysics来验证这一点。请参阅这些屏幕截图。

在动议之前: screen 1 经过一点动作 screen 2 走得更远 screen 3 就在接触之前 screen 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中添加更多代码,以重置physicsBody中每个myWorld的位置。

2 个答案:

答案 0 :(得分:0)

我注意到,一旦猴子接触,所有物理身体都会重新回到正确的位置。但是,关节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];

答案 1 :(得分:0)

我不知道过去两年发生了什么变化,但这里的另一个答案已不再适用了。相反,现在我将绳索段位置与其父级(完整绳索)组合在一起。所以我只是做

<textarea rows="4" cols="50"  type="text" name="ytburl" /></textarea>       
<input type="submit" value="START" name="submit" />

$ytburl = $_POST["ytburl"];
echo 'link '.$ytburl.' is here'

这是必要的,因为绳索段被放置在绳索的整个长度下,因此它的位置是相对于整个绳索而不是场景。