如何将 Sprite Kits 物理转换为绝对点值?

How to convert Sprite Kits physics into absolute points values?

我正在开发一款垂直 2D 平台自动跳投游戏。关卡生成是使用模式和自适应难度按程序完成的。游戏将在 iOS / OS X 上发布并使用 Apples Sprite Kit 框架。

物理是使用 Sprite Kit 自己的物理引擎实现的。例如,跳跃是通过施加力或改变玩家实体的当前速度来完成的。类似的东西:

playerEntity.physicsComponent.velocity =
    CGVectorMake(playerEntity.physicsComponent.velocity.dx, 850.0)

让玩家保持自己的 "flow zone" 自适应难度非常重要。这需要使用独特的模式来提供独特的挑战情境。

模式是使用程序概念生成的。但这需要了解玩家的物理行为,尤其是跳跃距离。

一种方法是手动硬编码一些跳跃距离。一种更灵活的方法是从物理系统中获取跳跃距离 - 或跳跃半径和 'air time' 等细节。

不幸的是,在 Sprite Kit 中没有真正的力向量单位的等效点。

所以我在问如何将Sprite Kit的物理转换成绝对点值。我需要一个函数,我可以输入一个力向量,然后输出玩家可能跳跃区域的半径。

如果我对 Sprite Kit 物理学的工作原理有所了解,例如 'pixel per frame' 速率,但我想那不存在!?类似于以下内容:

/// Returns a rectangle describing an oval area in absolute points
func jumpRadius(withPhysicsBody body: SKPhysicsBody, 
                andVector vector: CGVector) -> CGRect {

    // Compute area using physics body properties like mass, friction, etc.
    // Return it ...
    return ...
}

Philip Dick,我最喜欢的科幻作家之一,在 1978 年写了这篇文章 How to Build a Universe That Doesn't Fall Apart Two Days Later。以下是摘录:

Reality is that which, when you stop believing in it, doesn't go away.

让我们看看这与您的问题和我的回答有什么关系。

错误的方法

这是对您问题的简短回答。如果您想将 Hero 精灵的 position 转换为视图系统,您可以添加以下 属性

class Hero: SKSpriteNode {
    var globalPosition: CGPoint? {
        guard let scene = self.scene else { return nil }
        let pointInScene = self.convertPoint(self.position, toNode: scene)
        return scene.convertPointToView(pointInScene)
    }
}

为什么它不起作用

现在,如果您的游戏确实使用了物理学,那么您的游戏确实存在于一个(虚拟)物理世界中,其中距离以米为单位,不是 点,不是像素。

点和像素只是在平面屏幕上表示您在物理世界中模拟的更为复杂的现实的一种方式。视觉表示应该取决于物理世界,但物理世界中发生的事情应该完全与视觉表示无关。最重要的是不应受此影响。

否则,当您更改场景适合设备屏幕的方式时,假设替换它

scene.scaleMode = .AspectFill

有了这个

scene.scaleMode = .AspectFit

进入你的 GameViewController 你会遇到严重的麻烦,因为这确实改变了点和米之间的关系(我相信我们可以找到更多这样的例子)。

正确的方法

我的建议是:在您的物理世界中以米为单位进行计算。即使没有人在看它(即根本没有图形表示时)它也应该工作。