2017-05-12 27 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. 
}