2016-11-04 12 views
1

SKSpriteNodeを使用してSpriteKitでオーバーレイを作成しようとしています。しかし、オーバーレイを通したいので、isUserInteractionEnabledをfalseに設定します。しかし、私がこれを行うと、SKSpriteNodeは依然としてすべてのタッチを吸収しているように見え、根底にあるノードは何もすることができません。isUserInteractionEnabledが無効の場合、SKSpriteNodeはパススルーを許可しません。

は、ここで私が話しているかの例です:

class 

TouchableSprite: SKShapeNode { 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     print("Touch began") 
    } 
} 

class GameScene: SKScene { 
    override func sceneDidLoad() { 
     // Creat touchable 
     let touchable = TouchableSprite(circleOfRadius: 100) 
     touchable.zPosition = -1 
     touchable.fillColor = SKColor.red 
     touchable.isUserInteractionEnabled = true 
     addChild(touchable) 


     // Create overlay 
     let overlayNode = SKSpriteNode(imageNamed: "Fade") 
     overlayNode.zPosition = 1 
     overlayNode.isUserInteractionEnabled = false 
     addChild(overlayNode) 
    } 
} 

私はSKSpriteNodeをサブクラス化して、手動で適切なノードへのタッチイベントを委任しようとしたが、それは奇妙な行動の多くになります。

ご協力いただければ幸いです。ありがとう!

/** 
    Controls whether or not the node receives touch events 
*/ 
open var isUserInteractionEnabled: Bool 

をが、これはタッチの内部ノードメソッドを参照します。

+0

のために8、9、および10の間で確認する必要がありますので、あなたのZPOSITIONシーンを下回っているので、あなたのZORDERがoverlay-> scene->で、ケースはなかったかもしれませんtouchable – Knight0fDragon

答えて

3

あなたはZPOSITIONと注意する必要があります。シーンの後ろにいて、物事を複雑にすることは可能です。

タッチイベントの順序が悪いのは何ですか?私はzPositionではなく、ノードツリーに基づいていることを読んで覚えています。シーンのタッチを無効にすると、結果が表示されます。

ヒットテストの順序は、シーンの描画順序の逆で、 SpriteKitベースをタッチまたはマウスイベントを処理するとき、それは 最も近いを見つけるために、シーンを歩く:これは、それが今言っていることである

イベントを受け入れるノード。そのノードが イベントを望んでいない場合、SpriteKitは次に近いノードをチェックします。ヒットテストが処理される の注文は、基本的に 図面の逆順です。

ヒットテスト中にノードを検討するには、 のuserInteractionEnabledプロパティをYESに設定する必要があります。シーンノード以外のノードでは、デフォルト値 はNOです。 イベントを受信するノードでは、親クラス(iOSではUIResponder、OS XではNSResponder)の から適切なレスポンダメソッドを実装する必要があります。 SpriteKitには、プラットフォーム固有のコードを実装する必要がある数少ない場所のうちの1つが です。

しかし、これは常にあなたが一貫

+0

これは一種の知恵であり、少年の喜劇であり、彼の最善を尽くす男性の指摘された解説です。ありがとうございました。 – Confused

3

あなたが見つけ、実際のソースを読みます。 デフォルトではisUserInteractionEnabledです。オーバーレイのような子のタッチSKSpriteNodeは、デフォルトではメイン(または親)クラスに対して単純なタッチが処理されます(オブジェクトはここに存在しますが、あなたは単純にそれに触れる)

あなたのオーバーレイをタッチすると、あなたのGameSceneに以下のようなコードを実装することができます。-1を使用しないことを思い出してください。これはあなたのシーンの下にあることを意味します。

P.S.:私はtouchesBeganにそれを思い出して、あなたのスプライトにnameを追加しましたが、あなたはあなたのGameSceneにグローバル変数を作成することができます。

override func sceneDidLoad() { 
     // Creat touchable 
     let touchable = TouchableSprite(circleOfRadius: 100) 
     touchable.zPosition = 0 
     touchable.fillColor = SKColor.red 
     touchable.isUserInteractionEnabled = true 
     touchable.name = "touchable" 
     addChild(touchable) 
     // Create overlay 
     let overlayNode = SKSpriteNode(imageNamed: "fade") 
     overlayNode.zPosition = 1 
     overlayNode.name = "overlayNode" 
     overlayNode.isUserInteractionEnabled = false 
     addChild(overlayNode) 
    } 
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     print("GameScene Touch began") 
     for t in touches { 
      let touchLocation = t.location(in: self) 
      if let overlay = self.childNode(withName: "//overlayNode") as? SKSpriteNode { 
       if overlay.contains(touchLocation) { 
        print("overlay touched") 
        if let touchable = self.childNode(withName: "//touchable") as? TouchableSprite { 
         if touchable.contains(touchLocation) { 
          touchable.touchesBegan(touches, with: event) 
         } 
        } 
       } 
      } 
     } 
    } 
} 
関連する問題