Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Centering the camera on a node in swift spritekit

I am creating a Terraria-style game in Swift. I want to have it so the player node is always in the center of the screen, and when you move right the blocks go left like in Terraria.

I am currently trying to figure out how to keep the view centered on the character. Does anyone know of a good way of accomplishing this?

like image 486
bob Avatar asked Dec 10 '22 23:12

bob


2 Answers

Since iOS 9 / OS X 10.11 / tvOS, SpriteKit includes SKCameraNode, which makes a lot of this easier:

  • positioning the camera node automatically adjusts the viewport
  • you can easily rotate/zoom the camera by transform in the camera node
  • you can fix HUD elements relative to the screen by making them children of the camera node
  • the scene's position stays fixed, so things like physics joints don't break the way they do when you emulate a camera by moving the world

It gets even better when you combine camera nodes with another new feature, SKConstraint. You can use a constraint to specify that the camera's position is always centered on a character... or add extra constraints to say, for example, that the camera's position must stay within some margin of the edge of the world.

like image 59
rickster Avatar answered Dec 27 '22 12:12

rickster


The below will center the camera on a specific node. It can also smoothly transition to the new position over a set time frame.

class CameraScene : SKScene {
    // Flag indicating whether we've setup the camera system yet.
    var isCreated: Bool = false
    // The root node of your game world. Attach game entities 
    // (player, enemies, &c.) to here.
    var world: SKNode?
    // The root node of our UI. Attach control buttons & state
    // indicators here.
    var overlay: SKNode?
    // The camera. Move this node to change what parts of the world are visible.
    var camera: SKNode?

    override func didMoveToView(view: SKView) {
        if !isCreated {
            isCreated = true

            // Camera setup
            self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
            self.world = SKNode()
            self.world?.name = "world"
            addChild(self.world)
            self.camera = SKNode()
            self.camera?.name = "camera"
            self.world?.addChild(self.camera)

            // UI setup
            self.overlay = SKNode()
            self.overlay?.zPosition = 10
            self.overlay?.name = "overlay"
            addChild(self.overlay)
        }
    }


    override func didSimulatePhysics() {
        if self.camera != nil {
            self.centerOnNode(self.camera!)
        }
    }

    func centerOnNode(node: SKNode) {
        let cameraPositionInScene: CGPoint = node.scene.convertPoint(node.position, fromNode: node.parent)

        node.parent.position = CGPoint(x:node.parent.position.x - cameraPositionInScene.x, y:node.parent.position.y - cameraPositionInScene.y)
    }

}

Change what’s visible in the world by moving the camera:

// Lerp the camera to 100, 50 over the next half-second.
self.camera?.runAction(SKAction.moveTo(CGPointMake(100, 50), duration: 0.5))

Source: swiftalicio - 2D Camera in SpriteKit

For additional information, look at Apple's SpriteKit Programming Guide (Example: Centering the Scene on a Node).

like image 38
sangony Avatar answered Dec 27 '22 12:12

sangony