Набор Custom Class Sprite

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

Я уже делал что-то подобное, используя протоколы:

protocol CustomNodeEvents{
    func didMoveToScene()
}

Этот протокол находится в файле GameScene перед началом занятия. Затем я вызываю такую ​​функцию в классе GameScene:

override func didMove(to view: SKView) {

if let customnode = player as? CustomNodeEvents{
       customnode.didMoveToScene()
   }
}

Где игрок определяется как:

player = self.childNode(withName: "//player") as! SKSpriteNode

также внутри функции didMove(для просмотра: SKView).

Теперь я создал еще один файл (мой собственный файл класса) и пишу:

import SpriteKit

class Custom: SKSpriteNode, CustomNodeEvents{
    func didMoveToScene() {
         print("It Worked")
    }
}

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

Мой вопрос в том, как я могу заставить его работать? И второй вопрос: это лучший способ определить пользовательский класс и «связать» его с другими классами?

РЕДАКТИРОВАТЬ:


class GameScene: SKScene {

    var player: SKSpriteNode!

override func didMove(to view: SKView) {

    player = self.childNode(withName: "//player") as! SKSpriteNode

    if let customnode = player as? CustomNodeEvents{
       customnode.didMoveToScene()
    }

person DevX10    schedule 19.10.2016    source источник
comment
хм, ты опечатался в протоколе? у вас есть CustomNodeEvents(), должен ли он быть на нем ()?   -  person Knight0fDragon    schedule 19.10.2016
comment
Кроме того, мне кажется, что player может быть SKSpriteNode, а не Custom, поэтому в вашем случае if let вы получаете условие отказа, пропуская didMoveToScene   -  person Knight0fDragon    schedule 19.10.2016
comment
Я бы дважды проверил файл SKS, чтобы убедиться, что пользовательский класс плеера определен как Custom, а затем сделал бы player = self.childNode(withName: "//player") as! Custom. Если это не удается, то мы знаем, в чем проблема   -  person Knight0fDragon    schedule 19.10.2016
comment
@Knight0fDragon, это просто опечатка, отредактировано! Как я уже сказал, он работает без каких-либо ошибок. Над вторым комментарием тоже подумал, пытаюсь разобраться чего не хватает, так как до обновления работало (по крайней мере этот процесс работал, не обязательно тот пример который я написал)   -  person DevX10    schedule 19.10.2016
comment
Когда вы пишете код условия так, как вы это делаете, попытайтесь оценить потребность в нем. Если вам нужно гарантировать, что игрок должен существовать, разверните необязательное или укажите условие else. Если оставить такой if без защиты, отладка станет болезненной, и это приведет к нежелательным результатам, когда оно будет запущено в производство. Последнее, чего вы хотите, это чтобы он сломался у ваших клиентов, и они не смогут объяснить, как он сломался.   -  person Knight0fDragon    schedule 19.10.2016
comment
Я попытался развернуть плеер как Custom, и у меня нет ошибок, но он все равно не запускает функцию. Меня интересует история развертывания, не могли бы вы написать ответ с примером, чтобы я знал, что вы имеете в виду под оператором else ...?   -  person DevX10    schedule 19.10.2016
comment
if let customnode = player as? CustomNodeEvents{ customnode.didMoveToScene() } } else { print("Error casting customnode")} Вы также можете использовать assert, чтобы он вылетал на правильной строке   -  person Knight0fDragon    schedule 19.10.2016
comment
подождите, где вы определяете игрока? Возможно, вы устанавливаете его ПОСЛЕ вызова didMove( to view)   -  person Knight0fDragon    schedule 19.10.2016
comment
Я понял, спасибо за очистку этой части, теперь я все еще думаю, как использовать протоколы, или даже если есть лучший способ   -  person DevX10    schedule 19.10.2016
comment
@Knight0fDragon Отредактировано, чтобы показать объявление и определение   -  person DevX10    schedule 19.10.2016
comment
Сделал точно по твоему коду, у меня работает   -  person Knight0fDragon    schedule 19.10.2016


Ответы (2)


Не уверен, в чем проблема, но этот код работает для меня:

import SpriteKit
protocol CustomNodeEvents
{
    func didMoveToScene()
}
class Custom : SKSpriteNode,CustomNodeEvents
{
    func didMoveToScene()
    {
        print("It Worked")
    }
}


class GameScene:SKScene{

    var player : SKSpriteNode!
    override func didMove(to view: SKView) {

        player = self.childNode(withName: "//player") as! SKSpriteNode
        if let customnode = player as? CustomNodeEvents
        {
            customnode.didMoveToScene()
        }
        else
        {
            print("Error creating node")
        }
    }

}

Я могу только сделать вывод, что проблема в файле sks, и проигрыватель, который мы захватываем, не тот проигрыватель, который вы ищете, или проигрыватель не класса Custom. (Обратите внимание, я поместил спрайт игрока на самый верхний уровень сцены)

person Knight0fDragon    schedule 19.10.2016
comment
Спасибо за ответ, я действительно запутался, возможно, обновление xcode не печатает мне строку, потому что оно работает без ошибок, но ничего не печатается - person DevX10; 19.10.2016
comment
у меня все печатается и работает как положено, создайте новый проект, замените gamescene моим кодом, перейдите к файлу sks, перейдите на вкладку медиатеки в правом нижнем углу, перетащите космический корабль, назовите спрайт, дайте ему пользовательский класс, сохраните сцену и бегите. Вы увидите, что это работает - person Knight0fDragon; 19.10.2016
comment
Это сработало, большое спасибо! Но это странно, поскольку кажется, что проблема заключалась в использовании color sprite вместо изображения. Я только что заметил, что он говорит об ошибке при создании узла, но я все еще могу получить доступ к игроку и изменить его положение, когда выбираю цветной спрайт. В чем может быть проблема? - person DevX10; 19.10.2016
comment
Это означает, что вы получаете не пользовательский класс, а узел спрайта. - person Knight0fDragon; 19.10.2016
comment
Это заставляет меня думать, что это ошибка xcode, которая не сохраняется, когда я даю цветному спрайту собственный класс. - person DevX10; 19.10.2016
comment
ошибка на 100%, приятель, у меня она работает на цветных узлах. Убедитесь, что вы нажимаете ENTER, когда заканчиваете вводить имя. - person Knight0fDragon; 19.10.2016
comment
Я на 100% уверен, что он не сохранил состояние объекта, когда я нажимаю ENTER. Уже не первый раз не сохраняет состояние объекта после его изменения. Я просто научился вручную сохранять файл каждый раз, чтобы быть полностью уверенным :/ - person DevX10; 19.10.2016
comment
он сохраняет его каждый раз, у меня не было проблем с редактором, если вы находитесь в режиме редактирования текста и покидаете вкладку, все возвращается, чего и следовало ожидать. - person Knight0fDragon; 19.10.2016

Похоже, вы преобразуете player в SpriteNode, а затем пытаетесь преобразовать его в протокол CustomNodeEvents. Предполагая, что ваш пользовательский класс спрайта установлен в файле .sks, как вы говорите, SpriteKit должен создать экземпляр вашего пользовательского класса, чтобы вы могли просто сделать:

if let customNode = self.childNode(withName: "//player") as! Custom {
   customNode.didMoveToScene()
}
person jlyonsmith    schedule 19.10.2016
comment
Ммм, я думаю, я понимаю, на самом деле я объявил игрока в начале как: - person DevX10; 19.10.2016
comment
var player: SKSpriteNode! - person DevX10; 19.10.2016
comment
@jlyonsmith, вы идете против логики протокола. Что делать, если игрок уже не Custom, а какой-то другой класс? - person Knight0fDragon; 19.10.2016
comment
(Извините за многочисленные комментарии) Дело в том, что я хочу сделать функцию update внутри класса Custom в конце. И делать этот поиск игрока каждый раз стоило бы очень дорого! - person DevX10; 19.10.2016