Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simulate a world larger than the screen in SpriteKit?

I'm looking for the proper SpriteKit way to handle something of a scrollable world. Consider the following image:

enter image description here

In this contrived example, the world boundary is the dashed line and the blue dot can move anywhere within these boundaries. However, at any given point, a portion of this world can exist off-screen as indicated by the image. I would like to know how I can move the blue dot anywhere around the "world" while keeping the camera stationary on the blue dot.

like image 699
naivedeveloper Avatar asked Mar 16 '23 05:03

naivedeveloper


2 Answers

This is Adventure, a sprite kit game by apple to demonstrate the point I made below. Read through the docs, they explain everything

Theres a good answer to this that I can't find at the moment. The basic idea is this:

  1. Add a 'world' node to your scene. You can give it a width/height that is larger than the screen size.
  2. When you 'move' the character around (or blue dot), you actually move your world node instead, but in the opposite direction, and that gives the impression that you're moving.

This way the screen is always centered on the blue dot, yet the world around you moves

below is an example from when I was experimenting a while ago:

override func didMoveToView(view: SKView) {
        self.anchorPoint = CGPointMake(0.5, 0.5)
        //self.size = CGSizeMake(600, 600)

        // Add world
        world = SKShapeNode(rectOfSize: CGSize(width: 500, height: 500))
        world.fillColor = SKColor.whiteColor()
        world.position = CGPoint(x: size.width * 0.5, y: size.height * 0.5)
        world.physicsBody?.usesPreciseCollisionDetection = true
        self.addChild(world)
}

override func update(currentTime: CFTimeInterval) {
        world.position.x = -player.position.x
        world.position.y = -player.position.y
}
like image 65
duxfox-- Avatar answered Apr 24 '23 23:04

duxfox--


override func didSimulatePhysics() {
    self.centerOnNode(self.camera)
}

func centerOnNode(node: SKNode) {
        if let parent = node.parent {
            let nodePositionInScene: CGPoint = node.scene!.convertPoint(node.position, fromNode: parent)
            parent.position = CGPoint(
                    x: parent.position.x - nodePositionInScene.x,
                    y: parent.position.y - nodePositionInScene.y)
        }}

If you create a "camera" node which you add to your "world" node, a couple of simple functions (above) allow you to "follow" this camera node as it travels through the world, though actually you are moving the world around similar to Abdul Ahmad's answer.

This method allows you to use SpriteKit functionality on the camera. You can apply physics to it, run actions on it, put constraints on it, allowing effects like:

  • camera shaking (an action),
  • collision (a physics body, or matching the position of another node with a physics body),
  • a lagging follow (place a constraint on the camera that keeps it a certain distance from a character, for example)

The constraint especially adds a nice touch to a moving world as it allows the "main character" to move around freely somewhat while only moving the world when close to the edges of the screen.

like image 40
Attackfarm Avatar answered Apr 24 '23 22:04

Attackfarm