2013-11-26 4 views
3

Есть ли способ подключиться к жизненному циклу SKNode в пакете Sprite? В частности, я хотел бы выполнить некоторый код, когда узел будет удален из сцены.Метод вызова при удалении узла из SKScene

Вариант использования, который я хотел бы решить более подробно: У меня есть несколько узлов, которые взаимодействуют друг с другом, и я хотел бы, чтобы они были уведомлены о некоторых событиях, которые происходят с другими узлами. Например, представьте игру, в которой вы можете нажать узел на сцене, а детали узла появятся на HUD. Я хотел бы, чтобы HUD исчез, когда узел удаляется со сцены. Я планирую использовать NSNotificationCenter в качестве механизма уведомления. Всякий раз, когда узел удаляется со сцены, я хотел бы опубликовать уведомление. Самый простой способ - связать метод жизненного цикла с SKNode (мои узлы - это подклассы SKSpriteNode), например nodeWasRemovedFromParent, но я не нашел такого метода.

Как это можно сделать?

Я поразмыслил над своим собственным решением, переопределив метод removeFromParent в моем подклассе SKSpriteNode и разместив уведомление перед вызовом супер-реализации. Я не уверен, что метод removeFromParent всегда будет вызываться. Например, вызывает ли это вызов при смене сцен?

Спасибо.

ответ

4

Вам необходимо подклассы каждого класса узлов. Переопределите метод removeFromParent, как вы сказали. Используйте только подклассифицированные версии, иначе ваш код не вступит в силу.

Кроме того, вы захотите переопределить removeAllChildren и removeChildrenInArray: или просто не используйте их.

Метод removeFromParent не будет вызываться при смене сцены. Вместо этого переопределите метод сцены willMoveFromView: и отправьте сообщение зарегистрированным наблюдателям или просто всем дочерним узлам рекурсивно. Для этого используйте функцию перечисления сцены. Заметьте, что я не на 100% уверен, что на willMoveFromView дети сцены все еще прикреплены, я предполагаю, что они это сделают.

К сожалению, невозможно просто подкласс SKNode, а затем ожидать, что код подкласса будет работать для всех других классов узлов, потому что этот подкласс из SKNode напрямую, а не ваш собственный подкласс SKNode. Следовательно, вам необходимо подклассы и добавить этот код в каждый подкласс SK * Node, если вам нужно, чтобы он был уведомлен об удалении.

См. Классы узлов KoboldKit для примера, который использует макрос для ввода этого «переопределяющего» кода в подклассы SK * Node, чтобы избежать дублирования кода. Фактическая функциональность находится в KKNodeShared: https://github.com/KoboldKit/KoboldKit/tree/master/KoboldKit/KoboldKitFree/Framework/Nodes/Framework

+0

Спасибо, рассмотрим также примеры. Я не ожидаю, что подкласс SKNode (позволяет вызвать NotificationNode) removeFromParent для вызова для каждого узла, конечно. Я планирую изменить класс суперклассов собственных классов узлов на NotifyingNode, чтобы он работал. Также мне не нужна эта функция для работы со всеми узлами, только мои пользовательские узлы. Поэтому при повторении итерации в willMoveFromView у детей я могу проверить каждый ребенок, если они являются подклассами NotifyingNode. – utrutr

+0

@ LearnCocos2d Можно ли использовать категорию здесь, а не SubClassing? Не уверен, есть ли ограничения для переопределения методов через категорию. – prototypical

+0

В этом проблема, вы не можете (надежно) переопределить существующий метод с категорией. Плюс, даже если вы его swizzle, кажется, что иерархия классов не поддерживается в Sprite Kit, классы ObjC являются просто оболочками для классов C++. Поэтому вместо SKSpriteNode, вызывающего (swizzled) супер-реализацию removeFromParent на SKNode, он, кажется, вызывается непосредственно в базовый движок C++. – LearnCocos2D

Смежные вопросы