67138


別クラスのメソッドを使用してNodeをdidMoveで表示させたいのですが、下記コードでは表示されません。

何卒宜しくお願い致します。

**現状のコード**

[code]

    class GameScene: SKScene, SKPhysicsContactDelegate {
    
        let enemy = Enemy()
    
        override func didMove(to view: SKView) {
            self.enemy.addEnemy()
        }
    }
    
    class Enemy: SKScene, SKPhysicsContactDelegate {
    
        let enemyNode = SKSpriteNode(imageNamed: "enemy")
    
        func addEnemy() {
            enemyNode.position = CGPoint(x: 0, y: 0)
            enemyNode.size = CGSize(width: 50, height: 50)
            enemyNode.zPosition = 1.0
            addChild(enemyNode)
        }
    }
    
[/code]


CC BY-SA 4.0
2020-05-28T14:39:57.460
67089
2020-05-30T05:52:59.117
2020-05-28T16:48:02.190
3060
39881
question
swift xcode spritekit
Swift SpriteKit 別クラスのメソッドを使用したい


いただいたコメントの内容から、

  * `Enemy`を別クラスとしたのは _コードを綺麗にしたいと考え、Nodeの情報をまとめようと考えて_ のこと
  * `SKScene`のサブクラスにしたのは、`addChild(_:)`メソッドを使いたかったから

と言うことだと解釈しました。

* * *

_Nodeの情報をまとめ_ るのであれば、別質問であったような、`SKSpriteNode`のサブクラスとするのはいかがでしょうか?

コメントに書いた「別の`SKScene`のインスタンスを作って、そのなかで`addChild`のようなメソッドを呼んでも、画面に表示されることはありません」というのを解決する方法ですが、`addChild`は`SKScene`の公開メソッドなので、「ある`SKSceneが`(今の場合`GameScene`)表示されているとき」そのインスタンスそのものを引数として渡してやれば、`addChild(_:)`メソッドを呼ぶことができます。(別のインスタンスを作ってはいけない。)

[code]

    class EnemyNode: SKSpriteNode {
        static let enemy = EnemyNode(imageNamed: "enemy")!
    
        static func addEnemy(to scene: SKScene) {
            let enemyNode = EnemyNode.enemy
            enemyNode.position = CGPoint(x: 0, y: 0)
            enemyNode.size = CGSize(width: 50, height: 50)
            enemyNode.zPosition = 1.0
            scene.addChild(enemyNode)
        }
    }
    
[/code]

`GameScene`の側では、こんなふうに使います。

[code]

    class GameScene: SKScene, SKPhysicsContactDelegate {
    
        override func didMove(to view: SKView) {
            EnemyNode.addEnemy(to: self) //<- `self`が表示されている`SKScene`のインスタンスそのものを表す
        }
    }
    
[/code]

* * *

上記の方法だとstatic変数`EnemyNode.enemy`に`EnemyNode`のインスタンスを保持しているので、アプリ全体で1個だけ`EnemyNode`が存在する場合にしか使えません。

`EnemyNode`が複数になる場合のことを考えたら、こうした方が良いかもしれません。

[code]

    class EnemyNode: SKSpriteNode {
        //このメソッドの中で毎回`EnemyNode`のインスタンスを作成する
        static func addEnemy(to scene: SKScene) -> EnemyNode {
            let enemyNode = EnemyNode(imageNamed: "enemy")
            enemyNode.position = CGPoint(x: 0, y: 0)
            enemyNode.size = CGSize(width: 50, height: 50)
            enemyNode.zPosition = 1.0
            scene.addChild(enemyNode)
            //作成したインスタンスを戻り値として返す
            return enemyNode
        }
    }
    
[/code]

呼び出す方の`GameScene`の側は、

[code]

        var enemyNode: EnemyNode?
    
        override func didMove(to view: SKView) {
    
            enemyNode = EnemyNode.addEnemy(to: self)
    
            //...
        }
    
[/code]

* * *

どちらかのやり方を取り入れられそうであれば、試してみてください。


CC BY-SA 4.0
2020-05-30T05:52:59.117
67138
2020-05-30T05:52:59.117
13972
67089
answer