I'm working on a sidescroller with Spritekit and Swift. I don't understand how to define a playable area bigger than the screen and center the camera on the player. How can this be done?
This is my current code, I tried to create a "world node" which I could move around to simulate the camera, however it's somehow disassociated from it's shape and I haven't been able to get the player inside it.
override func didMoveToView(view: SKView) {
self.anchorPoint = CGPointMake(0.5, 0.5)
self.physicsWorld.contactDelegate = self
self.size = CGSizeMake(view.bounds.size.width, view.bounds.size.height)
// Add world
let r : CGRect = CGRectMake(0, 0, 500, 500)
world = SKShapeNode(rectOfSize: r.size)
world.physicsBody = SKPhysicsBody(edgeLoopFromRect: r)
world.strokeColor = SKColor.blackColor()
world.position = CGPointMake(0, 0)
self.addChild(world)
// Add player
player = SKShapeNode(rectOfSize: CGSize(width: 50, height: 50))
player.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 50, height: 50))
player.fillColor = SKColor.blackColor()
player.position = CGPointMake(0, 0)
world.addChild(player)
// Accelerometer updates
motionManager.startAccelerometerUpdates()
}
The example in Apple's documentation is in the Advanced Scene Processing section. Apple suggests making a "World" SKNode as a child of the Scene, and a "Camera" SKNode as a child of the world.
They suggest constantly moving the world so that it centers on the Camera during the didSimulatePhysics step. This method allows you to perform actions or simulate physics on the Camera itself, if you so choose. If you center the camera prior to this step, you won't be able to use physics to affect the Camera Node.
If you specifically only want left and right scrolling, simply restrict the movement to the X-axis.
Edit: The current problem is because of your creation of the world and the physicsBody from a Rect that has its position predetermined. This is causing trouble with your anchorPoint setting (the world & physicsBody are being created with their lower left corners starting at the Scene's anchor point).
This can be fixed by creating the World and Player without using a Rect with position set. SKShapeNode's
shapeNodeWithRectOfSize
works, as does SKSpriteNode'sspriteNodeWithColor:size:
PhysicsBody is a bit trickier, and should likely usebodyWithEdgeLoopFromPath: world.path
EDIT: For future persons interested in creating a side-scroller with a camera always focused on the player, this is probably the simplest way to get one to work:
I followed Ray Wenderlich's tutorial on a side scrolling game Super Koalio (or something like that). That game is a side scroller where the game map is larger sideways than the screen. The following code is for my game which is a vertical scrolling game.
In the update method I call a method called setViewPointCenter.
Then in that method you just update the view
Now my character is always in the center of the screen. I did change some items from horizontal to vertical, but at least you get an idea. Also, I used a tile map that is why you see mapSize and tileSize. You might want to take a look at Ray's tutorial. And of course you will need to convert into the methods into Swift!!