iOS - SpriteKit - 如何计算两个节点之间的距离?

13

我在屏幕上有两个sks节点。如何最好地计算它们之间的距离(即直线距离,不需要向量等)?

我已经用谷歌和这里的搜索了一下,但找不到相关内容(stackoverflow上关于sprite kit的主题并不多)。

5个回答

24

这是一个可以为您完成该操作的函数,代码示例来自苹果公司的Adventure游戏:

CGFloat SDistanceBetweenPoints(CGPoint first, CGPoint second) {
    return hypotf(second.x - first.x, second.y - first.y);
}

要从您的代码中调用此函数:

CGFloat distance = SDistanceBetweenPoints(nodeA.position, nodeB.position);

6

另一种快速的方法,由于我们处理的是距离,我添加了abs()函数以使结果始终为正数。

extension CGPoint {
    func distance(point: CGPoint) -> CGFloat {
        return abs(CGFloat(hypotf(Float(point.x - x), Float(point.y - y))))
    }
}

“Swift”(快速)真是太棒了,不是吗?

这帮了我很多!谢谢。 - TheValyreanGroup
1
abs() 是必要的吗?hypot() 不总是返回非负值吗? - Kristopher Johnson

5

joshd 和 Andrey Gordeev 都是正确的,其中 Gordeev 的解决方案阐述了 hypotf 函数的作用。

但是平方根函数是一个很耗费资源的函数。如果你只需要相对距离,可以跳过它;只有当你需要知道实际距离时才需要使用它。你可能想知道哪个精灵最靠近、最远,或者是否有任何精灵在半径范围内。在这些情况下,只需比较距离的平方。

- (float)getDistanceSquared:(CGPoint)p1 and:(CGPoint)p2 {
    return pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2);
}

要在SKScene子类的update:方法中使用此功能来计算任何精灵是否在视图中心的半径范围内:

-(void)update:(CFTimeInterval)currentTime {
    CGFloat radiusSquared = pow (self.closeDistance, 2);
    CGPoint center = self.view.center;
    for (SKNode *node in self.children) {
        if (radiusSquared > [self getDistanceSquared:center and:node.position]) {
            // This node is close to the center.
        };
    }
}

使用(p2.x-p1.y)*(p2.x-p1.y)可以大幅提高性能,而不是使用pow,因为pow是用于接收两个双精度浮点数的。 - Tim
另外,您可以使用powf,它接受两个浮点数。 - Austin
这是一个很棒的技巧,我以前从未想到过!谢谢。 - colinta

4

Swift:

extension CGPoint {

    /**
    Calculates a distance to the given point.

    :param: point - the point to calculate a distance to

    :returns: distance between current and the given points
    */
    func distance(point: CGPoint) -> CGFloat {
        let dx = self.x - point.x
        let dy = self.y - point.y
        return sqrt(dx * dx + dy * dy);
    }
}

你会如何使用这个?我理解了传递给dx和dy的后半部分的意义,但是self是什么,它是如何出现的? - Confused
@confused 由于这是一个扩展,我猜测它增加了在CGPoint实例上调用.distance()的能力,因此您可以像这样使用它:var theDistance = point1.distance(point2) - bluegreen

0

勾股定理:

- (float)getDistanceBetween:(CGPoint)p1 and:(CGPoint)p2 {
    return sqrt(pow(p2.x-p1.x,2)+pow(p2.y-p1.y,2));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接