Обнаружение сенсорных событий на узлах SKSpriteNode - PullRequest
0 голосов
/ 24 сентября 2018

поэтому здесь есть несколько похожих вопросов, но они на самом деле не отвечают на мои вопросы / проблемы.

Следующее объяснение моего проекта может помочь, а может и не помочь, я добавляю его здесьна всякий случай ...

Я пытаюсь создать свою первую игру для iOS, и я создал сцену, используя редактор сцен.Сцена содержит SKNode с именем "World".Затем есть backgroundNode и foregroundNode, которые являются дочерними элементами мирового узла.Все, что сейчас на сцене, все SKSpriteNodes, являются потомками backgroundNode.

В моем файле GameScene.swift у меня есть переменные, прикрепленные к узлам фона и переднего плана, чтобы я мог добавить детей к этим узлам в качестве игрыпрогрессирует.

Надеюсь, это пока ясно ...

Теперь я добавил 5 других файлов * .sks в свой проект.Этот файл содержит созданные мной сцены, которые будут добавлены как дочерние узлы переднего плана через код в моем файле GameScene.swift.Узлы SKSpriteNode в этих файлах сцены размещаются на переднем плане, но их позиция z меньше, чем позиция z одного из дочерних узлов фона.Это потому, что я хочу, чтобы за световым лучом появлялась коробка (световой луч отделен от фона, а коробка добавлена ​​на передний план).Вот изображение на случай, если я вызвал какую-либо путаницу Picture Of Boxes that were added to the foreground node appearing behind the lights that are children of the background node

Моя проблема заключается в следующем ... Я хочу нажимать на экран с помощью распознавателей жестов, чтобы при нажатии на полеТогда я могу сделать кое-что.Проблема в том, что, поскольку световой луч имеет большую z-позицию (причина нужного эффекта), каждый раз, когда я использую метод atPoint (_ p: CGPoint) -> SKNode, чтобы определить, на каком узле я нажал, я получаю возвращенный светузел луча, а не узел ящика.

Как мне коснуться только ящика?Я уже пытался изменить свойство isUserInteractionEnabled для источников света на false, и я попытался использовать touchesBegan, как показано во многих других ответах на аналогичный вопрос.Я также пытался читать документы разработчиков swift, предоставленные Apple, но я не могу понять это.

Код моего устройства распознавания жестов приведен ниже:

 //variables for gesture recognition
let tapGesture = UITapGestureRecognizer()
let swipeUpGesture = UISwipeGestureRecognizer()

//set up the tap gesture recognizer
tapGesture.addTarget(self, action: #selector(GameScene.tappedBox(_:)))
self.view!.addGestureRecognizer(tapGesture)
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1

//handles the tap event on the screen
@objc func tappedBox(_ recognizer: UITapGestureRecognizer) {

    //gets the location of the touch
    let touchLocation = recognizer.location(in: recognizer.view)
    if TESTING_TAP {
        print("The touched location is: \(touchLocation)")
    }

    //enumerates through the scenes children to see if the box I am trying to tap on can be detected (It can be detected using this just don't know how to actually detect it by tapping on the box)
    enumerateChildNodes(withName: "//Box1", using: { node, _ in
        print("We have found a single box node")
    })

    //tells me what node is returned at the tapped location
    let touchedNode = atPoint(touchLocation)
    print("The node touched was: \(String(describing: touchedNode.name))")

    //chooses which animation to run based on the game and player states
    if gameState == .waitingForTap && playerState == .idle{
        startRunning()              //starts the running animation
        unPauseAnimation()
    }else if gameState == .waitingForTap && playerState == .running {
        standStill()                //makes the player stand still
        unPauseAnimation()
    }
}

Надеюсь, этого достаточнодля вас, ребята ... Если вам нужен еще какой-нибудь код от меня, или мне нужно что-то уточнить, пожалуйста, дайте мне знать

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Вы хотите использовать nodesAtPoint, чтобы выполнить тест на попадание и получить все ваши узлы, которые связаны с точкой.Затем отфильтруйте список, чтобы найти поле, которое вы ищете.

Если у вас много слоев, вы также можете просто добавить невидимый слой поверх вашей графики, который обрабатывает узлы, которых касаются

Другой вариант - отключить isUserInteractionEnabled на всем, кроме ящиков, а затем переопределить события касания для своих ящиков, но это означает, что вы не можете использовать жесты, как сейчас.

0 голосов
/ 24 сентября 2018

Пожалуйста, прочитайте заметки в коде.Вы можете легко получить то, что хотите, в spriteKit.Надеюсь, вы получите ответ.

     @objc func tappedBox(_ recognizer: UITapGestureRecognizer) {

     let touchLocation = recognizer.location(in: recognizer.view)

  // Before you check the position, you need to convert the location from view to Scene. That's the right location.
     let point =  (recognizer.view as! SKView).convert(touchLocation, to: self)

      print ( getNodesatPoint(point, withName: "whatever Node name"  ) )
   }

 // 2 : This function  gives you all nodes with the name you assign. If you node has a unique name, you got it.
 ///     You can change name to other properties and find out.

     private func   getNodesatPoint(_ point : CGPoint , withName name: String) -> [SKNode] {
           return self.nodes(at: point).filter{ $0.name == name}
   }
...