SpriteKit touchesMoved 在 SKSpritenode 的子类中使用时不稳定

Posted

技术标签:

【中文标题】SpriteKit touchesMoved 在 SKSpritenode 的子类中使用时不稳定【英文标题】:SpriteKit touchesMoved is erratic when used in a subclass of SKSpritenode 【发布时间】:2016-11-24 20:20:05 【问题描述】:

我正在继承 SKSpritenode(在 Swift 中)来创建可以在场景中拖动的彩色块。子类是 SoundNode。

import SpriteKit

class SoundNode: SKSpriteNode 

init() 
    super.init(texture: nil, color: UIColor.blue, size: CGSize(width: 100, height: 100))
    self.isUserInteractionEnabled = true

    

required init?(coder aDecoder: NSCoder) 
    fatalError("init(coder:) has not been implemented")
    



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    print("touch began")
    

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 
    print("touches moved")
    guard let touch = touches.first else 
        return
           
    let touchLocation = touch.location(in: self)
    self.position = touchLocation
    


override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) 
    print("touch ended")
    



在 GameScene.swift 中

import SpriteKit

class GameScene: SKScene 

  override func didMove(to view: SKView) 
    addSoundBlock()
  


  func addSoundBlock() 
    let soundBlock = SoundNode()
    soundBlock.position = CGPoint(x: 800, y: 800)
    addChild(soundBlock)
    

这行得通。

添加了声音块,并且可以在场景中拖动。但它会闪烁,有时会消失。 我已经尝试过 touchesMoved 中的其他方法,但都没有影响到抖动。

如果我不对 touchesBegan、touchesMoved、touchesEnded 进行子类化,并在 GameScene 中实现这些动作,那么拖动就会变得平滑。但未来的计划取决于能否将这些子类化。

Xcode 8、Swift 3、ios10

【问题讨论】:

嘿,Rich,你查到了这件事的真相吗?我正在考虑类似的事情。 我的直觉是:let touchLocation = touch.location(in: self) 应该指的是场景框架中的触摸位置,而不是精灵(自身)的框架中。 我只能通过不对行为进行子类化来修复它。所以我把 touchesBegan 和其他动作移到了 GameScene.swift 这行得通,但感觉很乱。不知道我是否应该保持打开状态或将其作为解决方案发布。 【参考方案1】:

我创建了一个类方法来处理 SKSpriteNode 的子类(在我的例子中是“Player”)的移动,并将 GameScene.swift 中的触摸位置传递给它。

Player.swift 中的类方法声明:

    func movePlayer(location: CGPoint) 
        //movement code
    

调用GameScene.swift中的函数:

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) 

         guard let location = touches.first?.location(in: self) else  return 
         player.movePlayer(location: location)

    

我想有点清洁。并允许进一步的子类化。

【讨论】:

【参考方案2】:

当未设置 zPosition 以确保精灵位于其他节点之前时,我有时会发现精灵的外观不一致(即有时可见,有时不可见)。我认为这可能是因为如果两个节点具有相同的 zPosition,则图形引擎无法确保哪个节点位于顶部。 尝试将 zPosition 设置为某个数字,以确保它位于其他节点的前面。 例如之后:

soundBlock.position = CGPoint(x: 800, y: 800)

添加:

soundBlock.zPosition = 1000

我还没有尝试过运行它,但可能值得一试?

【讨论】:

以上是关于SpriteKit touchesMoved 在 SKSpritenode 的子类中使用时不稳定的主要内容,如果未能解决你的问题,请参考以下文章

SpriteKit touchesMoved 在 SKSpritenode 的子类中使用时不稳定

如何在 SpriteKit 中呈现场景后立即接收触摸事件?

SpriteKit:如何检测从节点外部开始的节点上的触摸

SourceKitService 终止,没有 Xcode 警告或错误

Touchesmoved - 一次拖动更新多个元素

如何让 touchesMoved 只控制一个视图?