Как правильно инкапсулировать обработку сенсорных событий в SKSpriteNode и передавать данные обратно в SKScene - PullRequest
0 голосов
/ 13 апреля 2020

Я пишу игру в SpriteKit, в которой есть джойстик для управления игроком. Ранее я сохранял большую часть логики джойстика c в основных методах GameScene touchesBegan, touchesMoved и touchesEnded.

Поскольку у меня несколько SKScenes, я хотел абстрагировать это logi c в SKSpriteNode подкласс JoyStick, который содержит свои touches обработчики событий. Это кажется хорошим решением, поскольку оно автоматически обрабатывает, находится ли касание «в границах» джойстика, и позволяет мне удалить логи c из самой сцены.

Однако я не могу найти любые хорошие ресурсы, описывающие, как правильно передавать информацию назад и вперед между экземплярами SKScene и SKSpriteNode, в которых реализованы обработчики сенсорных событий. Я мог бы передать JoyStick экземпляр объекта, который я хочу изменить (например, спрайт плеера), но мне любопытно, есть ли правильный способ передачи данных назад и вперед без привязки джойстика к указанному c «экземпляр для изменения» .

Кроме того, есть ли какие-либо иные недостатки в реализации обработчиков сенсорных событий в моих экземплярах SKSpriteNode, кроме обработки всего в обработчиках сцены?

1 Ответ

1 голос
/ 14 апреля 2020

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

Нет недостатков в удалении этого кода и несколько недостатков.

Более чистый код ускоряет загрузку в xcode, если в сценах меньше строк (мои собственные выводы), вам не нужно точно определять узел, на который приземляется касание, потому что он инкапсулирован в подкласс

в подкласс (cat)

protocol CatDelegate: class{
    func catTouched(cat: Cat)
}

class Cat: SKSpriteNode {

    weak var delegate: CatDelegate!

    var isEnabled = true
    var sendTouchesToScene = true
    var color: SKColor = .white

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent!) {

         guard isEnabled else { return }

         //send touch to scene if you need to handle further touches by the scene
         if sendTouchesToScene {
             super.touchesBegan(touches, with event)
         }

         //handle touches for cat
         delegate?.catTouched(cat: self)
    }
}

между тем в игровой сцене ...

class GameScene: SKScene {

    private var cat1: Cat!
    private var cat2: Cat!

    …

    func createCats() {

     cat1 = Cat()
        cat1.color = .magenta
        cat1.delegate = self
        addChild(cat1)

        cat2 = Cat()
        cat2.color = .green
        cat2.delegate = self
        addChild(cat2)
    }
}

extension GameScene: CatDelegate {

    func catTouched(cat: Cat) {
        print("cat of color \(cat.color)")
    }
}
...