SpriteKit stage camera clip

therefore, I have a basic game setup, which can be found on the bitpacket link below:

Game link

I currently have a hard time understanding how to translate a node camera in relation to a scene layout.

The goal is for the camera to follow the player until it comes across an angular border defined by the size of the scene. In this particular test case setup, the scene size is 1000x1000 with a camera scale of 1.

The code below is used to reposition the camera when a new position is set to follow the symbol:

var cameraPosition: CGPoint { get { return CGPoint(x: camera!.position.x, y: camera!.position.y) } set { let cameraScale = CGFloat(1) let sceneScale = CGFloat(1)//CGFloat(1 - 0.44 + 0.05 /*possible rounding error adjustment*/) // let viewAspectRatio = CGRectGetWidth(view!.frame)/CGRectGetHeight(view!.frame) let newPositionValue = double2(x: Double(newValue.x * sceneScale), y: Double(newValue.y * sceneScale)) let scaledSceneSize = CGSize(width: size.width * sceneScale , height: size.height * sceneScale) //// scaledSceneSize.height = scaledSceneSize.height / viewAspectRatio let cameraSize = view!.bounds.size let scaledCameraSize = CGSize(width: cameraSize.width * cameraScale, height: cameraSize.height * cameraScale) let minX = 0//-scaledSceneSize.width * anchorPoint.x + scaledCameraSize.width / 2 let minY = -219//-scaledSceneSize.height * anchorPoint.y + scaledCameraSize.height / 2 let minValues = double2(x: Double(minX), y: Double(minY)) let maxX = 0//(scaledSceneSize.width * anchorPoint.x - scaledCameraSize.width / 2) //size.width - cameraSize.width / 2 let maxY = 219//(scaledSceneSize.height * anchorPoint.y - scaledCameraSize.height / 2) //- cameraSize.height / 2 let maxValues = double2(x: Double(maxX), y: Double(maxY)) let clampedPosition = clamp(newPositionValue, min: minValues, max: maxValues) camera!.position = CGPoint(x: (clampedPosition.x / Double(sceneScale)), y: (clampedPosition.y / Double(sceneScale))) } } 

There is a tough value that currently matches the size of the desired scene, and I'm not sure how to get these results on a scale. Default Scale:

 /* Set the scale mode to scale to fit the window */ scene.scaleMode = .AspectFill 

Without knowledge of the knowledge of translation there on a scale, by default, I would expect that the boundaries would be mostSceneDimensionXValue - cameraSize.width / 2 mostSceneDimensionYValue - cameraSize.height / 2

As an example of a high level. Can anyone help me get this translation?

In general, the scene should look like this in all angles: target

VS having a black background in the frame as such:

anti goal

+5
source share
2 answers

Applications like this apply specifically to SKConstraint for.

You can see a demonstration of this exact function - holding the camera so that it follows the player but does not display too much empty space around the edge of the level - in the WWDC15 Deepening session in GameplayKit with DemoBots . * (The link there should jump until about 7:27 in the conversation, where the discussion of this function begins.)

The bottom line is that in the video, with some fragments from the DemoBots example example:

  • Use the distance limit to keep the camera focused on the player (automatically, without having to set camera.position directly on each update() ).

     // Constrain the camera to stay a constant distance of 0 points from the player node. let zeroRange = SKRange(constantValue: 0.0) let playerBotLocationConstraint = SKConstraint.distance(zeroRange, toNode: playerNode) 
  • Use position restriction to keep the camera within a specific edge range. Calculate this range by taking the level frame and the insert, which will be located at a distance that the camera should keep from the edge of the level.

     // get the scene size as scaled by `scaleMode = .AspectFill` let scaledSize = CGSize(width: size.width * camera.xScale, height: size.height * camera.yScale) // get the frame of the entire level contents let boardNode = childNodeWithName(WorldLayer.Board.nodePath)! let boardContentRect = boardNode.calculateAccumulatedFrame() // inset that frame from the edges of the level // inset by `scaledSize / 2 - 100` to show 100 pt of black around the level // (no need for `- 100` if you want zero padding) // use min() to make sure we don't inset too far if the level is small let xInset = min((scaledSize.width / 2) - 100.0, boardContentRect.width / 2) let yInset = min((scaledSize.height / 2) - 100.0, boardContentRect.height / 2) let insetContentRect = boardContentRect.insetBy(dx: xInset, dy: yInset) // use the corners of the inset as the X and Y range of a position constraint let xRange = SKRange(lowerLimit: insetContentRect.minX, upperLimit: insetContentRect.maxX) let yRange = SKRange(lowerLimit: insetContentRect.minY, upperLimit: insetContentRect.maxY) let levelEdgeConstraint = SKConstraint.positionX(xRange, y: yRange) levelEdgeConstraint.referenceNode = boardNode 
  • Apply both restrictions to SKCameraNode .

     camera.constraints = [playerBotLocationConstraint, levelEdgeConstraint] 

For a deeper look, download the Apple DemoBots sample code project , which has a lot of comments and supporting code that I cut from the above snippets so that this post does not get too long. Everything to restrict the camera is in the func setCameraConstraints() in LevelScene.swift .

* Despite the name of the session, it is much more than just GameplayKit ... it shows how to use many of the technologies introduced in iOS 8 / OS X 10.11 / Xcode 7 to create something that looks like a full-blown game: Thinning app, new SpriteKit, ReplayKit, and more.

+3
source

I have not used your code. I made a sample project and got this job.

enter image description here

heres my code

 import SpriteKit class GameScene: SKScene { let world = SKSpriteNode(imageNamed: "world.jpg") let player = SKSpriteNode(color: SKColor.greenColor(), size: CGSizeMake(10, 10)) var cam: SKCameraNode! override init(size: CGSize) { super.init(size: size) print(world.size) addChild(world) addChild(player) world.zPosition = 1 player.zPosition = 2 cam = SKCameraNode() self.camera = cam addChild(cam) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { for touch: AnyObject in touches { let location = touch.locationInNode(self) player.position = location } } override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { for touch: AnyObject in touches { let location = touch.locationInNode(self) player.position = location } } func clampCamera(){ func clamp(inout input: CGFloat, num1: CGFloat, num2: CGFloat) { if input < num1 { input = num1 } else if input > num2 { input = num2 } } let lBoundary = -world.size.width/2 + size.width/2 let rBoundary = world.size.width/2 - size.width/2 let bBoundary = -world.size.height/2 + size.height/2 let tBoundary = world.size.height/2 - size.height/2 clamp(&camera!.position.x, num1: lBoundary, num2: rBoundary) clamp(&camera!.position.y, num1: bBoundary, num2: tBoundary) } override func update(currentTime: NSTimeInterval) { camera!.position = player.position clampCamera() } } 

this is the same image that I used as my "world", http://i.imgur.com/XhZbh8q.jpg

+2
source

Source: https://habr.com/ru/post/1242026/


All Articles