Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit pan in my scene #17

Open
leandersantosm opened this issue Apr 9, 2018 · 3 comments
Open

Limit pan in my scene #17

leandersantosm opened this issue Apr 9, 2018 · 3 comments

Comments

@leandersantosm
Copy link

leandersantosm commented Apr 9, 2018

Hi, I have another question.
Can I limit the pan in my scene?
I can pan infinitly and I want to use only the region of my tiles and a little of the border of the tiles.

I tried this way:

if position.x < 68 { position.x = 68 }
if position.x > 108 { position.x = 108 }
if position.y < 30 { position.y = 30 }
if position.y > 50 { position.y = 50 }

But when I zoom the camera, this positions change and It does not work properly anymore.
My tile map is little, about 7x4, and there is some pictures at its side, so it is pratically my workspace.
Is there a way to limit the pan to this little area, and be able to zoom limiting this same area?
Thanks!

@mfessenden
Copy link
Owner

I haven't implemented anything to automatically limit panning because that will be very specific to your game, but check out the included SKTiledSceneCameraDelegate protocol - it will update delegates when the camera position, zoom or bounds have changed. It should be easy to constrain the camera with the tilemap node with a SKContraint node.

@leandersantosm
Copy link
Author

I will try this! Thanks!!

@technicallyerik
Copy link
Contributor

This was my logic for an older version of SKTiled when cameraPanned was able to be overridden. But perhaps some of the math can help out:

    open func cameraPanned(_ recognizer: UIPanGestureRecognizer) {
        guard let scene = self.scene as? SKTiledScene else { return }
         
        let minPanX = (scene.size.halfWidth * zoom) - (scene.tilemap.sizeInPoints.halfWidth * zoom - ((scene.size.width * xScale) / 2)) - (panInsets.left * xScale)
        let maxPanX = (scene.size.halfWidth * zoom) + (scene.tilemap.sizeInPoints.halfWidth * zoom  - ((scene.size.width * xScale) / 2)) + (panInsets.right * xScale)
        let minPanY = (scene.size.halfHeight * zoom) - (scene.tilemap.sizeInPoints.halfHeight * zoom  - ((scene.size.height * yScale) / 2)) - (panInsets.bottom * yScale)
        let maxPanY = (scene.size.halfHeight * zoom) + (scene.tilemap.sizeInPoints.halfHeight * zoom - ((scene.size.height * yScale) / 2)) + (panInsets.top * yScale)
         
        if (recognizer.state == .began) {
            let location = recognizer.location(in: recognizer.view)
            lastLocation = location
        }
         
        if (recognizer.state == .changed) && (allowMovement == true) {
            if lastLocation == nil { return }
             
            let location = recognizer.location(in: recognizer.view)
            let difference = CGPoint(x: location.x - lastLocation.x, y: location.y - lastLocation.y)
             
            var newPositionX = position.x - (difference.x * self.xScale)
            if((scene.tilemap.sizeInPoints.width / xScale) * zoom < scene.size.width - (panInsets.left + panInsets.right)) {
                if(newPositionX < maxPanX) {
                    newPositionX = maxPanX
                }
                if(newPositionX > minPanX) {
                    newPositionX = minPanX
                }
            } else {
                if(newPositionX > maxPanX) {
                    newPositionX = maxPanX
                }
                if(newPositionX < minPanX) {
                    newPositionX = minPanX
                }
            }
             
            var newPositionY = position.y - -(difference.y * self.yScale)
            if((scene.tilemap.sizeInPoints.height / yScale) * zoom < scene.size.height - (panInsets.top + panInsets.bottom)) {
                if(newPositionY < maxPanY) {
                    newPositionY = maxPanY
                }
                if(newPositionY > minPanY) {
                    newPositionY = minPanY
                }
            } else {
                if(newPositionY > maxPanY) {
                    newPositionY = maxPanY
                }
                if(newPositionY < minPanY) {
                    newPositionY = minPanY
                }
            }
             
            centerOn(scenePoint: CGPoint(x: newPositionX, y: newPositionY))
             
            lastLocation = location
        }
    }

It handles zooming, and if the map is bigger than the screen, the map locks to the edges of the screen as you pan. It also handles if the map is smaller than the screen, the edges act as bumpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants