Mar*_*llD 7 touchesmoved ios sprite-kit swift
我正在使用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
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题并不总是会发生,所以有时你必须重启应用程序5次,但最终你会发现,如果你慢慢地拖动方块,那么它就会非常滞后.我也理解它有时很微妙,但是当扩大规模时,这是一个很大的问题.
我的主要问题: 为什么我有一个带有物理体的SKSpriteNode导致TouchesMoved()滞后而没有其他任何延迟,我该如何防止这种情况?
请为了爱的代码和我的理智,救我脱离这个深渊!
看起来这是由于操作系统太忙而无法响应触摸事件造成的。我找到了两种重现此问题的方法:
在设备上启用飞行模式,然后将其禁用。禁用飞行模式后约 5-10 秒内,触摸事件会出现滞后。
在 Xcode 中打开另一个项目,并在方案编辑器中选择“等待应用程序启动”,然后按“构建并运行”将应用程序安装到设备上而不运行它。安装应用程序时,触摸事件会滞后。
似乎没有解决这个问题的方法,但这里有一个解决方法。使用上一次更新的位置和时间,预测下一次更新的位置和时间,并将精灵动画到该位置。它并不完美,但效果很好。请注意,如果用户在屏幕上有多个手指,它就会中断。
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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
677 次 |
| 最近记录: |