2017-05-12 26 views
2

所以,我可以讓攝像機隨着播放器移動,但它不會按照我需要的方式進行操作。 我已經設置字邊界:Sprite套件延遲攝像機平滑移動

func keepPlayerInBounds() { 
    if player.position.x < frame.minX + player.size.width/2 { 
     player.position.x = frame.minX + player.size.width/2 
    } 

    if player.position.x > frame.maxX + player.size.width/2 { 
     player.position.x = frame.maxX + player.size.width/2 
    } 
} 

所以我需要相機的最大和最小X是爲最大,並在worldNode混合X播放器的位置。並隨着玩家向右或向左移動而延遲平滑。 我試圖設置:

override func didFinishUpdate() 
    cam.position.x = player.position.x 
} 

或者:

override func didFinishUpdate() { 
    let move = SKAction.moveTo(x: player.position.x, duration: 0.5) 
    cam.run(move) 
} 

但它帶來了比需要更多的頭痛。

問題是:如何設置攝像機的左右最大位置,並延遲移動它沒有錯誤。我花了差不多三個星期的時間找到答案,但仍然沒有任何結果。謝謝!

+0

你對「平滑運動」有什麼瞭解?你遇到什麼錯誤或頭痛? – Marc

+0

它正在快速或有一些困難 –

回答

1

一個簡單的方法來保持你的遊戲的界限是爲玩家設置一個物理實體,爲物理實體設置一個界限。

var player: SKSpriteNode! //player variable 
var map: SKSpriteNode! //this simple node called map is a variable that represents the bounds area, for the example i made it the size of the scene (inside GameScene.sks) 

override func didMove(to view: SKView) { 
    player = childNode(withName: "player") as! SKSpriteNode // initializing the player from the scene file. 
    player.physicsBody = SKPhysicsBody(rectangleOf: player.size) // initializing player physics body(in this example the player is a simple rectangle). 

    map = childNode(withName: "map") as! SKSpriteNode // initializing the map from the scene file. 
    map.physicsBody = SKPhysicsBody(edgeLoopFrom: map.frame) // instead of assigning a physics body to the scene it self, we created the map variable and assign the physics body to it, the edgeLoopFrom physics body is a static volume-less body, so the player will not be able to pass through. 

    setupCamera() // for the second part of your question we create this method and call it right here in viewDidLoad(). 
} 

而不是在更新()方法中不斷更新相機位置,您只需添加相機約束。 (我在場景文件中也添加了相機)

func setupCamera() { 
    guard let camera = camera, let view = view else { return } // make sure we have a camera and a view or else return 

    let zeroDistance = SKRange(constantValue: 0) 
    let playerConstraint = SKConstraint.distance(zeroDistance, 
               to: player) // as the name suggest this is a simple constraint for the player node. 
    //next part of the method will assign a second constraint to the camera which will prevent the camera from showing the dark area of the scene in case the player will go to the edge. you don't have to add this part but it is recommended. 
    let xInset = min(view.bounds.width/2 * camera.xScale, 
        map.frame.width/2) 
    let yInset = min(view.bounds.height/2 * camera.yScale, 
        map.frame.height/2) 

    let constraintRect = map.frame.insetBy(dx: xInset, 
                dy: yInset) 

    let xRange = SKRange(lowerLimit: constraintRect.minX, 
         upperLimit: constraintRect.maxX) 
    let yRange = SKRange(lowerLimit: constraintRect.minY, 
         upperLimit: constraintRect.maxY) 

    let edgeConstraint = SKConstraint.positionX(xRange, y: yRange) 
    edgeConstraint.referenceNode = map 

    camera.constraints = [playerConstraint, edgeConstraint] //finally we add the constraints we created to the camera, notice that the edge constraint goes last because it has a higher priority. 
}