swiftsprite-kitskcameranode

How to identify specific nodes in SKCamera's view?


I am trying to recycle same SKSpriteNode to make continuous background. I created SKSpriteNode as bg0, bg1, bg2 and positioned them properly when presenting the scene. Somehow, below code ONLY re-positions bg0 once.

cam is SKCameraNode, therefore, I am checking whether camera contains the background nodes. Due to their size, always one of them should not be visible in the camera viewport. However, like I said this only works once and when camera shows recycled bg0 does not recognize it.

Thank you in advance.

PS: I already tried cam.intersects(bg0) as well, got the same result.

func updateBgPos() {
    if (player?.position.y)! > self.frame.height {
        if !cam.contains(bg0!) {
            print("bg0 is not in the scene")
            newPosBgY = (bg2?.position.y)! + self.frame.height
            bg0?.physicsBody = nil
            bg0?.position = CGPoint(x: self.frame.width / 2, y: newPosBgY)
            bg0?.physicsBody = bg1?.physicsBody
        } else if !cam.contains(bg1!) {
            print("bg1 is not in the scene")
            newPosBgY = (bg0?.position.y)! + self.frame.height
            bg1?.physicsBody = nil
            bg1?.position = CGPoint(x: self.frame.width / 2, y: newPosBgY)
            bg1?.physicsBody = bg0?.physicsBody
        } else if !cam.contains(bg2!) {
            print("bg2 is not in the scene")
            newPosBgY = (bg1?.position.y)! + self.frame.height
            bg2?.physicsBody = nil
            bg2?.position = CGPoint(x: self.frame.width / 2, y: newPosBgY)
            bg2?.physicsBody = bg1?.physicsBody
        }
    }
}

Solution

  • Well, finally I've figured it out how to achieve this. I hope this helps someone else.

    I initially created and placed two SKSpriteNode as background as bg0 and bg1 like below:

        bg0 = SKSpriteNode(imageNamed: "bg0")
        bg1 = SKSpriteNode(imageNamed: "bg1")
    
        bg0!.name = "bg0"
        bg1!.name = "bg1"
    
        bg0?.scale(to: CGSize(width: sceneWidth, height: sceneHeight))
        bg1?.scale(to: CGSize(width: sceneWidth, height: sceneHeight))
    
        bg0?.zPosition = zPosBg
        bg1?.zPosition = zPosBg
    
        backgroundArr.append(bg0!)
        backgroundArr.append(bg1!)
    
        bg0?.position = CGPoint(x: sceneWidth / 2, y: 0)
        bg1?.position = CGPoint(x: sceneWidth / 2, y: sceneHeight)
    
        self.addChild(bg0!)
        self.addChild(bg1!)
    

    After, on the update method I called below function:

    func updateBgPos() {
        guard let playerPosY = player?.position.y else { return }
        guard let bg0PosY = bg0?.position.y else { return }
        guard let bg1PosY = bg1?.position.y else { return }
    
        if playerPosY - bg0PosY > sceneHeight / 2 + camFollowGap {
            print("bg0 is not in the scene")
            newPosBgY = bg1PosY + sceneHeight
            bg0?.position = CGPoint(x: sceneWidth / 2, y: newPosBgY)
        } else if playerPosY - bg1PosY > sceneHeight / 2 + camFollowGap {
            print("bg1 is not in the scene")
            newPosBgY = bg0PosY + sceneHeight
            bg1?.position = CGPoint(x: sceneWidth / 2, y: newPosBgY)
        }
    }
    

    PS: camFollowGap is CGFloat value that I subtracted when I position my camera to the player. When dealing with continuous background I had to add that value into calculation to avoid positioning delay and appearances of temporary gaps between backgrounds.