gpt4 book ai didi

ios - 当存在带有物理体的 SkSpriteNode 时,TouchesMoved() 滞后非常不一致

转载 作者:搜寻专家 更新时间:2023-10-30 21:57:31 24 4
gpt4 key购买 nike

我正在使用 Swift 3.0、SpriteKit 和 Xcode 8.2.1,在运行 iOS 10.2 的 iPhone 6s 上进行测试。

问题很简单……从表面上看。基本上,我的 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 次,但最终您会发现,如果操作缓慢,拖动方 block 会非常缓慢。我也知道它有时很微妙,但是当扩大规模时这是一个大问题。

我的主要问题:为什么我有一个带物理体的 SKSpriteNode 会导致 TouchesMoved() 滞后而其他任何东西都不会滞后,我该如何防止这种情况发生?

请出于对代码的热爱和我的理智,将我从这个深渊中拯救出来!!!

最佳答案

看起来这是由于操作系统太忙而无法响应触摸事件造成的。我找到了两种重现此方法的方法:

  • 在设备上启用飞行模式,然后将其禁用。在禁用飞行模式后的约 5-10 秒内,触摸事件会滞后。

  • 在 Xcode 中打开另一个项目并在方案编辑器中选择“等待应用程序启动”,然后按“构建”和“运行”将应用程序安装到设备而不运行它。在安装应用时,触摸事件滞后。


这似乎没有解决办法,但这里有一个解决方法。使用上一次 更新时的位置和时间,预测下一次 更新时的位置和时间,并将 Sprite 动画到该位置。它并不完美,但效果很好。请注意,如果用户在屏幕上有多个手指,它就会中断。

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

关于ios - 当存在带有物理体的 SkSpriteNode 时,TouchesMoved() 滞后非常不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41527311/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com