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

时间:2015-05-30 04:22:57

标签: ios swift sprite-kit

我目前有一张离开屏幕的大地图,因此它的坐标系与我的其他节点非常不同。这导致了一个问题,因为我需要在这个地图的边界内生成一个随机的CGPoint,然后如果那个点是在帧/屏幕上我放置一个可见的节点那里。然而,节点在屏幕上的检查是否连续失败。

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

例如,在下面的图片中,箭头指向它的球位于场景坐标中的坐标(479,402)处,但它们实际上位于地图中的(9691,9753)&#39 ; s坐标。 enter image description here

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

因为如下所示,点显然位于帧中,但CGRectContainsPoint总是失败。我尝试过scene.convertPoint(position, fromNode: map),但它没有用。

编辑(澄清一些事情)

我的视图层次结构如下所示:enter image description here

地图节点离开屏幕,大小约为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中调用,请注意我将此应用于节点I' m生成 - 我只是将该代码留出来)。其中值是随机位置。

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

使屏幕外的节点不可见。 (因为用户可以滚动地图背景)。这总是传递为真,使所有节点都不可见,即使节点确实在帧内(如上图所示,我注释了清晰的颜色代码)。

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:2)

使用包含playerNode并在此节点上拥有摄像头中心的worldNode,您可以使用以下代码检查/关闭:

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;

将屏幕宽度向左和向右跳过2。对于screenHeight也一样。

相关问题