Check if node is visible on screen

I currently have a large map that is disconnected from the screen, which makes its coordinate system very different from my other nodes. This led me to a problem because I need to generate a random CGPoint within that map, and then if that point is a frame / on screen, I place a visible node there. However, checking to see if the node is on the screen doesn't work.

I am checking if a node is in a frame with the following code: CGRectContainsPoint(self.frame, values)

(with values ​​that are generated by a random CGPoint I). Now when my problem occurs, the frame coordinate system is completely different from the map coordinate system.

For example, in the image below, the ball with the arrows pointing at it is at coordinates (479, 402) in scene coordinates, but they are actually at (9691, 9753) in map coordinates. enter image description here

I have determined the coordinates using the touchsBegan event for anyone wondering. So, basically, how do I convert this map coordinate system to one that will work for a frame?

Since, as seen below, the point is obviously in the frame, however, CGRectContainsPoint always fails. I tried doing scene.convertPoint(position, fromNode: map)

it but it didn't work.

Edit: (to clarify some things)

My view hierarchy looks something like this: enter image description here

The node map goes off-screen and is about 10,000 Γ— 10,000 for size. (I have it like a scrolling map). The origin (or 0,0) for this node is in the lower left corner where the map starts, which means the origin is off-screen. In the picture above, I am approaching the upper right side of the map. I am generating a random CGPoint with the following code (Passing it in a card frame) as an extension for the 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;
}

      

Then I have the following code (Called in didMoveToView, please note that I am applying this to the nodes I generate - I just left this code behind). Where values ​​are random position.

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

      

So that nodes that are off-screen are invisible. (Since the user can scroll the background of the map). This always passes as true, making all nodes invisible, even if the nodes are indeed within the frame (As seen in the image above, where I commented out the crisp color code).

+3


source to share


2 answers


Using worldNode, which includes playerNode and has the center of the camera at that node, you can turn this code 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];
    }
}

      

The numbers I used above are static. You can also make them dynamic:



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

      

Diving screenWidth by 2 for left and right. Ditto for screenHeight.

+2


source


If I understand your question correctly, you have an SKScene that contains an SKSpriteNode that is larger than the scene view, and that you randomly generate coordinates in that sprite coordinate system that you want to map to the view.



You are on the right track with SKNode

convertPoint(_:fromNode:)

(where your scene is SKNode

and your map is fromNode

). This should take you from the generated map coordinate to the scene coordinate. Then we convert this coordinate to the view coordinate system using your scene convertPointToView(_:)

. The point will be out of bounds if it is not in the field of view.

+3


source







All Articles