3

我正在尝试构建一个 SpriteKit 游戏,该游戏涉及带有可以放大和缩小的物理主体的关卡。物理世界的行为不像我预期的那样,当缩放级别改变时会导致奇怪的事情发生。

具有物理实体的节点动画并按预期运行。缩放关卡是通过捏合手势来处理的,该手势正在调整包含所有游戏元素的单个“世界节点”的比例。这是一种方便的处理方式,因为缩放场景似乎会做可怕的事情,并且可以轻松地为世界节点顶部的任何游戏界面元素添加单独的未缩放节点。

缩放的工作原理如下:

- (void) handlePinchGesture:(UIPinchGestureRecognizer *) gesture {
    if (gesture.state == UIGestureRecognizerStateChanged) {
        [self.worldNode runAction:[SKAction scaleBy:gesture.scale duration:0.0]];
        gesture.scale = 1;
    }
}

在正常缩放级别时,一切都很好,并且在视觉上,在不同的缩放级别下一切看起来也很好。问题是当缩放改变时,物理实体继续以相同的速度移动,而不是相对于其他物体的相同速度。结果是当缩小以查看更多场景时,一切都移动得更快。

这似乎是物理世界仅连接到场景并且不知道“世界节点”的调整比例这一事实的副作用。物理体不应该在它们的相对空间中继续以相同的速度移动节点吗?

任何人都可以提供任何关于 SpriteKit 的行为方式的见解,或者如何解决这个问题?

4

2 回答 2

2

它以这种方式运行的原因是显而易见的。想象一下,你想把一个球缩小到一个更小的尺寸,它应该仍然以同样的方式移动,对吧?

出现问题是因为您同时缩放“整个球系统”。除了正在发生的事情之外,这没有任何真正明智的结果。SpriteKit 实际上需要猜测您要做什么,并根据它为使其工作而进行的缩放比例来缩放物理速度或不使用它。

解决方案是缩放整个场景而不是子节点。

编辑:要缩放您设置大小的场景。您需要将场景的 scaleMode 设置为 SKSceneScaleModeAspectFill。

Edit2:子场景解决方案只有在您将它们添加到专用的第二个 SKView 时才有效,而且我承认它相当牵强。您可能需要使用单个场景,上下缩放,相应地移动子节点并隐藏您的界面元素(或“反缩放它们”)。

于 2014-03-12T19:37:28.650 回答
1

这个答案基于@TheisEgeberg 在他的答案评论中建议的方法。做出这个答案是因为我认为它需要是一个答案而不是评论。如果他用这种方法更新他的答案,我会删除这个答案。将这种方法作为问题的答案将为人们省去很多麻烦。

1.创建一个包含物理节点的 SKScene。

2.创建一个 SKNode 将充当您的 SKScene 的模仿者

3.对于您创建并添加到 SKScene 的每个节点,您创建另一个模拟节点 - 但没有物理主体 - 并将其添加到模拟 SKNode;

4. 在您​​的 SKScene 中创建一个名为 updateMimicNodes 的方法,该方法遍历所有节点并更新相应节点的位置,即模拟节点中的 zRotation。从您的更新方法中调用该方法,因此它会在每一帧中更新。

5.随心所欲地缩放模拟节点。

6.使用 hidden 属性隐藏具有物理体的 SKScene 节点。如果将所有节点放在添加到 SKScene 的 SKNode 层上,则只需将该 SKNode 的 hidden 属性设置为 YES;

为了更容易管理,我在所有节点上创建了一个“模拟”属性,并将该属性设置为模拟节点上的相应节点。然后,您可以像这样更新更新中的每个节点:

node.mimic.position = node.position
node.mimic.zRotation = node.zRotation

稍后我可能会为这种方法发布一些示例代码,但是如果您按照这些步骤操作,您应该会到达应许之地。

还要记住,任何触摸都需要将位置转换为带有物理体的 SKScene 坐标系。

于 2015-01-12T00:10:09.757 回答