检测旋转何时完成并移动到新场景
Posted
技术标签:
【中文标题】检测旋转何时完成并移动到新场景【英文标题】:Detect when rotation has completed and move to new Scene 【发布时间】:2017-04-24 04:57:23 【问题描述】:我正在尝试在车轮停止旋转时移动到另一个场景。我的代码如下所示。我不知道如何检测速度何时达到 0.0?
import SpriteKit
import GameplayKit
class GameplayScene: SKScene
var player: Player?;
override func didMove(to view: SKView)
player = self.childNode(withName: "spinner") as! Player?;
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
for touch in touches
let location = touch.location(in: self)
if atPoint(location).name == "play_button"
spin()
func spin ()
let random = GKRandomDistribution(lowestValue: 20, highestValue: 90)
let r = random.nextInt()
player?.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(self.frame.width))
player?.physicsBody?.affectedByGravity = false
player?.physicsBody?.isDynamic = true
player?.physicsBody?.allowsRotation = true
player?.physicsBody?.angularVelocity = CGFloat(r)
player?.physicsBody?.angularDamping = 1.0
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
所以从这里开始,我想在车轮停止旋转时执行以下操作:
let play_scene = Questions(fileNamed: "QuestionsScene")
play_scene?.scaleMode = .aspectFill
self.view?.presentScene(play_scene!, transition: SKTransition.doorsOpenVertical(withDuration: 1))
我现在已经编辑了这个类,它看起来如下:
import SpriteKit
import GameplayKit
class GameplayScene: SKScene, SKSceneDelegate
var player: Player?
override func didMove(to view: SKView)
self.delegate = self
player = self.childNode(withName: "spinner") as! Player?;
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?)
for touch in touches
let location = touch.location(in: self)
if atPoint(location).name == "play_button"
spin()
func spin ()
let random = GKRandomDistribution(lowestValue: 20, highestValue: 90)
let r = random.nextInt()
player?.physicsBody = SKPhysicsBody(circleOfRadius: CGFloat(self.frame.width))
player?.physicsBody?.affectedByGravity = false
player?.physicsBody?.isDynamic = true
player?.physicsBody?.allowsRotation = true
player?.physicsBody?.pinned = true
player?.physicsBody?.angularVelocity = CGFloat(r)
player?.physicsBody?.angularDamping = 1.0
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?)
override func didSimulatePhysics()
if ((player?.physicsBody?.angularVelocity)! <= CGFloat(0.01))
print("Got it")
问题是我仍然收到关于 didSimulatePhysics 函数中的 if 语句的错误。我收到的错误是“线程 1:EXC_BAD_INSTRUCTION....”
【问题讨论】:
【参考方案1】:您的***的SKPhysicsBody
有一个内置属性angularVelocity
,它告诉您它的旋转速度。当您将其设置为 r
以开始旋转时,您已经在使用它了。
要观看angularVelocity
,您可以使用didSimulatePhysics()
。它每帧调用一次,就在物理计算完成之后。看起来像这样:
func didSimulatePhysics()
if wheelIsSpinning && angularVelocity != nil && angularVelocity! <= CGFloat(0.001)
wheelIsSpinning = false
// wheel has stopped
// add your code here
由于物理建模的变幻莫测,angularVelocity 可能永远不会完全为零。因此,我们改为观察它是否小于某个任意阈值,在本例中为 0.001。
您不希望它在***不移动时执行每一帧,所以我添加了一个属性wheelIsSpinning
来跟踪。您需要将其作为实例属性添加到GameplayScene
,并在spin()
中将其设置为true。
【讨论】:
谢谢罗伯特。后来我发现,即使当我将速度打印到控制台时,***看起来已经停止了,但它看起来仍然旋转得如此缓慢。它从未真正停止过 @Nick 只需检查.angularVelocity <= 0.001
或其他任意低值。
@Robert 将场景设置为自己的委托没有意义。在SKSceneDelegate
协议中找到的所有方法,包括didSimulatePhysics()
,都会在SKScene
及其子类上自动调用。设置一些其他类来实现这个协议会更有意义......
@Nick 除了您不需要该行之外,如果您仍然想要类似的东西,请将self.delegate = self
放入init()
或其他适当的方法中。你不能在类的主体中使用 self。
@Nick 从场景的定义中删除 SKSceneDelegate
一致性(你的场景应该看起来像这样 class GameplayScene: SKScene
。从你的代码中删除 self.delegate = self
。当你这样做时,告诉我错误是什么。一切否则罗伯特说,应该工作。符合SKSceneDelegate
是不必要的。这就是我的观点。以上是关于检测旋转何时完成并移动到新场景的主要内容,如果未能解决你的问题,请参考以下文章
每天一个Js小demo之移动端全景图场景实现-全景装修图。主要知识点:css3,旋转角度检测
如何检测 UINavigationController 动画何时完成?