SKCameraNode 跟不上移动节点
SKCameraNode doesn't keep up with moving node
我目前正在尝试制作一个 "launch(er) game",即使用 SpriteKit 的 Toss the turle、Learn to fly 和 Burrito Bison 风格的游戏。我已经使用 SpriteKit 的内置物理原理启动了工作,但是当我尝试使用 SKCameraNode 跟随主角时,似乎总是落后一步(或更多步)使主角 "shake" 在高速下。
我已经尝试使用 SKAction 和 .position-属性 设置相机的位置,结果相同。
我想这是因为物理更新的速度比实际更新 () 快,我尝试搜索相关信息但一无所获。
"launching"主角的功能:
func touchStopped(touchPoint: CGPoint) {
if !inAir {
arrow.removeFromParent()
inAir = true
mainCharNode.physicsBody = SKPhysicsBody(circleOfRadius: mainCharNode.size.width/2)
mainCharNode.physicsBody?.mass = mainChar.mass
mainCharNode.physicsBody?.restitution = mainChar.restitution
mainCharNode.physicsBody?.linearDamping = mainChar.airResistance
mainCharNode.physicsBody?.velocity = CGVectorMake(touchPoint.x*2, touchPoint.y)
mainCharNode.physicsBody?.categoryBitMask = mainCategory
mainCharNode.physicsBody?.collisionBitMask = groundCategory
} else {
mainCharNode.physicsBody?.applyImpulse(CGVectorMake(10000, 10000))
}
}
更新()-函数:
override func update(currentTime: CFTimeInterval) {
if lastUpdateTime > 0 {
dt = currentTime - lastUpdateTime
} else {
dt = 0
}
lastUpdateTime = currentTime
if mainCharNode.position.x > 1000 {
let moveCamera = SKAction.moveTo(CGPoint(x: mainCharNode.position.x, y: cameraNode.position.y), duration: dt)
cameraNode.runAction(moveCamera)
}
if(inAir && !gameOver) {
distance += (mainCharNode.physicsBody?.velocity.dx)!*CGFloat(dt)
if(mainCharNode.physicsBody?.velocity == CGVector(dx: 0,dy: 0)) {
gameOver = true
mainCharNode.physicsBody?.dynamic = false
}
}
}
https://github.com/CalleLundstedt/LauncherGame 这是 github 上的完整项目。
通过在 update
中手动设置相机位置,您将相机移动至少延迟一帧 — 物理在 update
之后运行,因此您的相机移动发生在您之后的帧上角色移动。
当您使用移动动作而不是直接设置位置并为该动作指定非零持续时间时,您会进一步延迟相机移动。 (代码中的 dt
是这一帧与之前最后一帧之间的时间,并且您将该时间应用于 future 运动。)因为角色是当你的动作运行时仍然在移动,相机永远不会赶上 - 你总是将相机移动到角色 是 的地方。
不过,设置相机位置只是给自己增加了额外的工作量。使用 SKConstraint
代替,SpriteKit 本身将确保相机位置固定在角色上——它在物理之后解决约束,但在同一帧上。
我目前正在尝试制作一个 "launch(er) game",即使用 SpriteKit 的 Toss the turle、Learn to fly 和 Burrito Bison 风格的游戏。我已经使用 SpriteKit 的内置物理原理启动了工作,但是当我尝试使用 SKCameraNode 跟随主角时,似乎总是落后一步(或更多步)使主角 "shake" 在高速下。
我已经尝试使用 SKAction 和 .position-属性 设置相机的位置,结果相同。
我想这是因为物理更新的速度比实际更新 () 快,我尝试搜索相关信息但一无所获。
"launching"主角的功能:
func touchStopped(touchPoint: CGPoint) {
if !inAir {
arrow.removeFromParent()
inAir = true
mainCharNode.physicsBody = SKPhysicsBody(circleOfRadius: mainCharNode.size.width/2)
mainCharNode.physicsBody?.mass = mainChar.mass
mainCharNode.physicsBody?.restitution = mainChar.restitution
mainCharNode.physicsBody?.linearDamping = mainChar.airResistance
mainCharNode.physicsBody?.velocity = CGVectorMake(touchPoint.x*2, touchPoint.y)
mainCharNode.physicsBody?.categoryBitMask = mainCategory
mainCharNode.physicsBody?.collisionBitMask = groundCategory
} else {
mainCharNode.physicsBody?.applyImpulse(CGVectorMake(10000, 10000))
}
}
更新()-函数:
override func update(currentTime: CFTimeInterval) {
if lastUpdateTime > 0 {
dt = currentTime - lastUpdateTime
} else {
dt = 0
}
lastUpdateTime = currentTime
if mainCharNode.position.x > 1000 {
let moveCamera = SKAction.moveTo(CGPoint(x: mainCharNode.position.x, y: cameraNode.position.y), duration: dt)
cameraNode.runAction(moveCamera)
}
if(inAir && !gameOver) {
distance += (mainCharNode.physicsBody?.velocity.dx)!*CGFloat(dt)
if(mainCharNode.physicsBody?.velocity == CGVector(dx: 0,dy: 0)) {
gameOver = true
mainCharNode.physicsBody?.dynamic = false
}
}
}
https://github.com/CalleLundstedt/LauncherGame 这是 github 上的完整项目。
通过在 update
中手动设置相机位置,您将相机移动至少延迟一帧 — 物理在 update
之后运行,因此您的相机移动发生在您之后的帧上角色移动。
当您使用移动动作而不是直接设置位置并为该动作指定非零持续时间时,您会进一步延迟相机移动。 (代码中的 dt
是这一帧与之前最后一帧之间的时间,并且您将该时间应用于 future 运动。)因为角色是当你的动作运行时仍然在移动,相机永远不会赶上 - 你总是将相机移动到角色 是 的地方。
不过,设置相机位置只是给自己增加了额外的工作量。使用 SKConstraint
代替,SpriteKit 本身将确保相机位置固定在角色上——它在物理之后解决约束,但在同一帧上。