SpriteKit 侧滚动不更新physicsWorld [英] SpriteKit side scrolling doesn't update physicsWorld

查看:13
本文介绍了SpriteKit 侧滚动不更新physicsWorld的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Following the example here (except in Objective C) and the standard Apple documentation, I discovered that the physicsWorld doesn't update its positions when myWorld updates its position. I turned on showsPhysics on my skView to verify this. See these screenshots.

在任何动作之前:稍作动作后走得更远一点就在联系之前

Before any motion: After a little motion Getting a little farther And just before contact

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

Here's my code for centering myWorld. Most of the length is due to me being extremely verbose in dealing with the edge limits.

- (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 的位置.

Is there an elegant way to fix this? So far my only idea is to include more code in centerOnNode that resets the positions of every physicsBody in myWorld.

推荐答案

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

I don't know what's changed in the last 2 years, but the other answer here didn't work anymore. Instead, now I combine the rope segments position with its parent's (the full rope). So I just do

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];

这是必需的,因为绳子段放置在绳子的全长之下,所以它的位置是相对于整个绳子而不是场景.

This is needed because the rope segment is placed under the full length of the rope, so it's position is relative to the full rope rather than the scene.

这篇关于SpriteKit 侧滚动不更新physicsWorld的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆