Sprite Kit相机平滑移动与延迟

3

所以,我可以让相机随着玩家移动,但它的表现并不符合我的需求。 我已经设置了单词边界:

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值设置为世界节点中玩家位置的最大和最小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)
}

但是它带来的麻烦比必要的还多。

问题是:如何设置摄像机的左右最大位置,并在延迟移动时避免错误。我花了将近三个星期去寻找答案,但仍然一无所获。谢谢!


你理解的“平滑移动”是什么?你遇到了哪些错误或问题? - Marc
它移动得太快或者有些卡顿。 - Yaroslav Sarnitskiy
1个回答

2

让您的游戏保持在边界内的更简单方法是为玩家设置一个物理身体,以及为边界设置一个物理身体。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接