精灵套件相机平滑移动,延迟

时间:2017-05-12 13:11:26

标签: ios swift camera sprite-kit

所以,我可以让相机随玩家移动,但它不会像我需要的那样动作。 我设置了字界限:

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)
}

但它带来了比需要更多的头痛。

问题是:如何设置摄像机的左右最大位置,并在没有错误的情况下延迟移动。我花了差不多三个星期的时间来找到答案,但仍然一无所获。谢谢!

1 个答案:

答案 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().
}

而不是在update()方法中不断更新摄像机位置,您只需添加摄像机约束。 (我也在场景文件中添加了相机)

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.
}