检查节点在屏幕上是否可见

Check if node is visible on the screen

我目前有一张大地图超出了屏幕范围,因此它的坐标系与我的其他节点非常不同。这让我遇到了一个问题,因为我需要在这张地图的边界内生成一个随机的 CGPoint,然后 if 那个点是 frame/on-screen 我放置一个可见的节点在那里。然而,检查节点是否在屏幕上不断失败。

我正在使用以下代码检查节点是否在框架中:CGRectContainsPoint(self.frame, values)(值是我生成的随机 CGPoint)。现在这就是我的问题所在,框架的坐标系与地图的坐标系完全不同。

比如下图中箭头所指的球在场景坐标中的坐标为(479, 402),但实际在地图坐标中为(9691, 9753)。

对于那些想知道的人,我使用 touchesBegan 事件确定了坐标。所以基本上,我如何将该地图坐标系转换为适用于框架的坐标系?

因为如下所示,点显然在框架中,但 CGRectContainsPoint 总是失败。我试过 scene.convertPoint(position, fromNode: map) 但没用。

编辑:(澄清一些事情)

我的视图层次结构如下所示:

地图节点超出屏幕范围,大小约为 10,000x10,000。 (我把它作为滚动类型的地图)。此节点的原点(或 0,0)位于左下角,地图开始的位置,这意味着原点在屏幕外。在上图中,我靠近地图的右上角。我正在使用以下代码(将其传递给地图框架)生成一个随机 CGPoint 作为 CGPoint 的扩展:

static func randPoint(within: CGRect) -> CGPoint {
    var point = within.origin

    point.x += CGFloat(arc4random() % UInt32(within.size.width))
    point.y += CGFloat(arc4random() % UInt32(within.size.height))

    return point;
}

然后我有以下代码(在 didMoveToView 中调用,请注意,我将其应用于我正在生成的节点 - 我只是将代码遗漏了)。其中 values 是随机位置。

let values = CGPoint.randPoint(map.totalFrame)
if !CGRectContainsPoint(self.frame, convertPointToView(scene!.convertPoint(values, fromNode: map))) { 
      color = UIColor.clearColor()
}

使屏幕外的节点不可见。 (因为用户可以滚动地图背景)。这始终为真,使所有节点不可见,即使节点确实在框架内(如上图所示,我在其中注释掉了清晰的颜色代码)。

如果我对你的问题的理解正确,你有一个 SKScene,其中包含一个比场景视图大的 SKSpriteNode,并且你在要映射到视图的精灵坐标系内随机生成坐标。

您在 SKNodeconvertPoint(_:fromNode:) 方面走在了正确的轨道上(您的场景是 SKNode,您的地图是 fromNode)。那应该让你从生成的地图坐标到场景坐标。接下来,使用场景的 convertPointToView(_:) 将该坐标转换为视图的坐标系。如果该点不在视野范围内,则该点将出界。

使用包含 playerNode 的 worldNode 并将相机中心放在该节点上,您可以使用以下代码检查 on/off:

float left = player.position.x - 700;
float right = player.position.x + 700;
float up = player.position.y + 450;
float down = player.position.y - 450;

if((object.position.x > left) && (object.position.x < right) && (object.position.y > down) && (object.position.y < up)) {
    if((object.parent == nil) && (object.dead == false)) {
        [worldNode addChild:object];
    }
} else {
    if(object.parent != nil) {
        [object removeFromParent];
    }
}

我上面使用的数字是静态的。您还可以使它们动态化:

CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;
CGFloat screenHeight = screenRect.size.height;

将 screenWidth 向左和向右扩展 2。 screenHeight 也一样。