Персонализиран комплект 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(to view: 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
освен това ми се струва, че играчът може да е 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
Когато пишете код на условие по начина, по който го правите, опитайте да оцените нуждата си от него. Ако трябва да гарантирате, че даден играч трябва да съществува, разгънете незадължителното или предоставете друго условие. Оставянето на 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
променлив играч: SKSpriteNode! - person DevX10; 19.10.2016
comment
@jlyonsmith, ти все пак противоречиш на логиката на протокола. Ами ако играчът вече не е персонализиран, а друг клас? - person Knight0fDragon; 19.10.2016
comment
(Съжалявам за множеството коментари) Въпросът е, че искам да направя функция update вътре в персонализирания клас в края. И това търсене на играча всеки път би струвало много! - person DevX10; 19.10.2016