[英]TouchesMoved() lagging very inconsistently when there is a SkSpriteNode with a physics body
我正在使用Swift 3.0,SpriteKit和Xcode 8.2.1,在運行iOS 10.2的iPhone 6上進行測試。
問題很簡單......表面上看。 基本上我的TouchesMoved()以非常不穩定的速率更新,並且正在破壞游戲中UI的基本部分。 有時候它完美地工作,一分鍾后它以一半的速率進行更新。
我已經解決了這個問題。 只是在具有物理體的場景中有一個SKSpriteNode會導致問題......這是我的GameScene代碼:
import SpriteKit
import Darwin
import Foundation
var spaceShip = SKTexture(imageNamed: "Spaceship")
class GameScene: SKScene{
var square = SKSpriteNode(color: UIColor.black, size: CGSize(width: 100,height: 100))
override func didMove(to view: SKView) {
backgroundColor = SKColor.white
self.addChild(square)
//This is what causes the problem:
var circleNode = SKSpriteNode(texture: spaceShip, color: UIColor.clear, size: CGSize(width: 100, height: 100))
circleNode.physicsBody = SKPhysicsBody(circleOfRadius: circleNode.size.width/2)
self.addChild(circleNode)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch in touches{
var positionInScreen = touch.location(in: self)
square.position = positionInScreen
}
}
}
這個問題並不總是會發生,所以有時你必須重啟應用程序5次,但最終你會發現,如果你慢慢地拖動方塊,那就非常遲了。 我也理解它有時很微妙,但是當擴大規模時,這是一個很大的問題。
我的主要問題:為什么我有一個帶有物理體的SKSpriteNode導致TouchesMoved()滯后而沒有其他任何延遲,我該如何防止這種情況?
請為了愛的代碼和我的理智,救我脫離這個深淵!
看起來這是因為操作系統太忙而無法響應觸摸事件。 我找到了兩種方法來重現這個:
在設備上啟用飛行模式,然后禁用它。 在禁用飛行模式后約5-10秒,觸摸事件滯后。
在Xcode中打開另一個項目,在方案編輯器中選擇“等待應用程序啟動”,然后按Build and Run將應用程序安裝到設備而不運行它。 在安裝應用程序時,觸摸事件滯后。
似乎沒有解決方法,但這是一個解決方法。 使用上次更新時的位置和時間,預測下次更新時的位置和時間,並將精靈設置為該位置的動畫。 它並不完美,但它的效果非常好。 請注意,如果用戶在屏幕上有多個手指,它會中斷。
class GameScene: SKScene{
var lastTouchTime = Date.timeIntervalSinceReferenceDate
var lastTouchPosition = CGPoint.zero
var square = SKSpriteNode(color: UIColor.black, size: CGSize(width: 100,height: 100))
override func didMove(to view: SKView) {
backgroundColor = SKColor.white
self.addChild(square)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
lastTouchTime = Date().timeIntervalSinceReferenceDate
lastTouchPosition = touches.first?.location(in: self) ?? .zero
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let currentTime = Date().timeIntervalSinceReferenceDate
let timeDelta = currentTime - lastTouchTime
for touch in touches{
square.removeAction(forKey: "TouchPrediction")
let oldPosition = lastTouchPosition
let positionInScreen = touch.location(in: self)
lastTouchPosition = positionInScreen
square.position = positionInScreen
//Calculate the difference between the sprite's last position and its current position,
//and use it to predict the sprite's position next frame.
let positionDelta = CGPoint(x: positionInScreen.x - oldPosition.x, y: positionInScreen.y - oldPosition.y)
let predictedPosition = CGPoint(x: positionInScreen.x + positionDelta.x, y: positionInScreen.y + positionDelta.y)
//Multiply the timeDelta by 1.5. This helps to smooth out the lag,
//but making this number too high cause the animation to be ineffective.
square.run(SKAction.move(to: predictedPosition, duration: timeDelta * 1.5), withKey: "TouchPrediction")
}
lastTouchTime = Date().timeIntervalSinceReferenceDate
}
}
使用touchesMoved
方法拖動圖像時遇到類似問題。 我之前只是根據觸摸的位置更新節點的位置,這使得移動看起來很滯后。 我這樣做得更好:
//in touchesMoved
let touchedPoint = touches.first!
let pointToMove = touchedPoint.location(in: self)
let moveAction = SKAction.move(to: pointToMove, duration: 0.01)// play with the duration to get a smooth movement
node.run(moveAction)
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.