I want to have background stationary with different objects (sprites and other objects).
Player will be represented by center node that will move around the world. I
There are few ways to make a camera follow SKNode. It depends on preferred type of scrolling.
A camera can be rigidly attached by adding it as child node of player:
let player = SKNode()
let camera = SKCameraNode()
override func didMove(to view: SKView) {
addChild(player)
player.addChild(camera)
}
It is important to note that position of camera should be corrected after all physics updates will be completed. Otherwise a screen can shakes if player or other object which the camera are followed moves with big velocity. It depends on order of updating of scene nodes and position of camera in node ieararchy. To avoid of this effect it's necessary to update position of camera in method didSimulatePhysics
:
let player = SKNode()
let camera = SKCameraNode()
override func didMove(to view: SKView) {
addChild(player)
addChild(camera)
}
// Vertical scrolling, moving only in y-axis
override func didSimulatePhysics() {
camera.position.y = player.position.y
}
// Horizontal scrolling, moving only in x-axis
// override func didSimulatePhysics() {
// camera.position.x = player.position.x
// }
The new SKCameraNode seems like a very easy way to do this.
https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKCameraNode/
Simply
1) create an SKCameraNode
// properties of scene class
let cam = SKCameraNode()
let player = SKSpriteNode()
2) add it to your scene camera property
// In your scene, for instance didMoveToView
self.camera = cam
3) make the camera follow your player position
override func update(currentTime: CFTimeInterval)
{
/* Called before each frame is rendered */
cam.position = player.position
}
let cam = SKCameraNode()
var player: SKSpriteNode?
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.camera = cam
player = SKSpriteNode(imageNamed: "Player")
if player?.position != nil {
player!.position = CGPoint(x: size.width / 2, y: size.height - 150)
self.addChild(player!)
}
player?.addChild(cam)
}
Using SKCameraNode
with SKConstraint
in Swift 5.1
let camera = SKCameraNode()
camera.constraints = [.distance(.init(upperLimit: 10), to: node)]
scene.addChild(camera)
scene.camera = camera
Something like this should help. I call the following from my didSimulatePhysics.
-(void)centerOnNode:(SKNode*)node {
CGPoint cameraPositionInScene = [node.scene convertPoint:node.position fromNode:node.parent];
cameraPositionInScene.x = 0;
node.parent.position = CGPointMake(node.parent.position.x - cameraPositionInScene.x, node.parent.position.y - cameraPositionInScene.y);
}
I realize this is similar to Stuart Welsh's answer; however, I'd like to make his good answer a bit more comprehensive.
Basically, Apple recommends that you create a "world" node to contain all of your other nodes, with the world being a child of the actual scene; and further that you create a "camera" node as a child of the world node.
Then, from your scene, you can do something like:
[self centerOnCameraNamed:myCameraName];
Which calls the method (also in your scene):
- (void)centerOnCameraNamed:(NSString*)cameraName
{
SKNode* world = [self childNodeWithName:worldName];
SKNode* camera = [world childNodeWithName:cameraName];
CGPoint cameraPositionInScene = [camera.scene convertPoint:camera.position fromNode:world];
world.position = CGPointMake(world.position.x - cameraPositionInScene.x, world.position.y - cameraPositionInScene.y);
}