Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly position the camera when panning

Tags:

I'm having a hard time setting boundaries and positioning camera properly inside my view after panning. So here's my scenario.

I have a node that is bigger than the screen and I want to let user pan around to see the full map. My node is 1000 by 1400 when the view is 640 by 1136. Sprites inside the map node have the default anchor point. Then I've added a camera to the map node and set it's position to (0.5, 0.5).

enter image description here

Now I'm wondering if I should be changing the position of the camera or the map node when the user pans the screen ? The first approach seems to be problematic, since I can't simply add translation to the camera position because position is defined as (0.5, 0.5) and translation values are way bigger than that. So I tried multiplying/dividing it by the screen size but that doesn't seem to work. Is the second approach better ?

var map = Map(size: CGSize(width: 1000, height: 1400))

override func didMove(to view: SKView) {
    (...)
    let pan = UIPanGestureRecognizer(target: self, action: #selector(panned(sender:)))
    view.addGestureRecognizer(pan)

    self.anchorPoint = CGPoint.zero
    self.cam = SKCameraNode()
    self.cam.name = "camera"

    self.camera = cam
    self.addChild(map)
    self.map.addChild(self.cam!)

    cam.position = CGPoint(x: 0.5, y: 0.5)
}

var previousTranslateX:CGFloat = 0.0

func panned (sender:UIPanGestureRecognizer) {
    let currentTranslateX = sender.translation(in: view!).x

    //calculate translation since last measurement
    let translateX = currentTranslateX - previousTranslateX

    let xMargin = (map.nodeSize.width - self.frame.width)/2

    var newCamPosition = CGPoint(x: cam.position.x, y: cam.position.y)
    let newPositionX = cam.position.x*self.frame.width + translateX

    // since the camera x is 320, our limits are 140 and 460 ?
    if newPositionX > self.frame.width/2 - xMargin && newPositionX < self.frame.width - xMargin {
        newCamPosition.x = newPositionX/self.frame.width
    }

    centerCameraOnPoint(point: newCamPosition)

    //(re-)set previous measurement
    if sender.state == .ended {
        previousTranslateX = 0
    } else {
        previousTranslateX = currentTranslateX
    }
}

func centerCameraOnPoint(point: CGPoint) {
    if cam != nil {
        cam.position = point
    }
}
like image 792
sasklacz Avatar asked Jan 24 '17 11:01

sasklacz


People also ask

When panning your camera should move in which direction?

2. Pan. Panning is when you move your camera horizontally; either left to right or right to left, while its base is fixated on a certain point. You are not moving the position of the camera itself, just the direction it faces.

What makes a good panning photo?

A good panning shot needs a slow shutter speed — about 1/30 to 1/80 of a second. While that's not a lot of time in human terms, it makes a great difference for the equipment. This exposes the sensor to light longer. It also gives a moving camera time to capture motion.

What is panning in camera movement?

types of camera movement movements is to turn, or pan (from the word panorama), the camera horizontally so that it sweeps around the scene. It can also be tilted up or down in a vertical panning shot or in a diagonal pan, as when it follows an actor up a stairway.


1 Answers

Your camera is actually at a pixel point 0.5 points to the right of the centre, and 0.5 points up from the centre. At (0, 0) your camera is dead centre of the screen.

I think the mistake you've made is a conceptual one, thinking that anchor point of the scene (0.5, 0.5) is the same as the centre coordinates of the scene.

If you're working in pixels, which it seems you are, then a camera position of (500, 700) will be at the top right of your map, ( -500, -700 ) will be at the bottom left.

This assumes you're using the midpoint anchor that comes default with the Xcode SpriteKit template.

Which means the answer to your question is: Literally move the camera as you please, around your map, since you'll now be confident in the knowledge it's pixel literal.

With one caveat...

a lot of games use constraints to stop the camera somewhat before it gets to the edge of a map so that the map isn't half off and half on the screen. In this way the map's edge is showing, but the furthest the camera travels is only enough to reveal that edge of the map. This becomes a constraints based effort when you have a player/character that can walk/move to the edge, but the camera doesn't go all the way out there.

like image 164
Confused Avatar answered Sep 22 '22 11:09

Confused