66729


メソッドを条件によって、呼び出すか止めるかを制御したいです。  
今回作成しているゲームアプリでは、画面上部からitemBox(node)が下部へ落ちます。  
そのitemBox(node)とspaceship(node)が接触した際に、item1をユーザーは取得します。  
その後、再度itemBox(node)とspaceship(node)が接触を行うとitem1が重複してしまいエラーが発生します。  
ですので、一度itemBox(node)とspaceship(node)が接触した場合はitemBox(node)の出現をストップしたいです。

まずこちらがitemBoxを出現させているメソッドです。  
didBigen内の「timar」で呼び出します。

[code]

        timar = Timer.scheduledTimer(withTimeInterval: 3.0, repeats: true, block: { _ in
            self.addItemBox()
        })
    
[/code]

itemBoxのメソッド↓

[code]

    func addItemBox() {
    
        let itemBox = SKSpriteNode(imageNamed: "itemBox")
        let xHighest:CGFloat = self.frame.maxX + itemBox.size.width
        let xLowest: CGFloat = self.frame.minX - itemBox.size.width
        let random = CGFloat.random(in: xLowest...xHighest)
        itemBox.position = CGPoint(x: random, y: frame.width)
        itemBox.size = CGSize(width: 60, height: 60)
    
        itemBox.physicsBody = SKPhysicsBody(circleOfRadius: itemBox.frame.width)
        itemBox.physicsBody?.categoryBitMask = itemBoxCategory
        itemBox.physicsBody?.collisionBitMask = spaceshipCategory | itemBoxCategory
        itemBox.physicsBody?.contactTestBitMask = spaceshipCategory
        addChild(itemBox)
    
        let move = SKAction.moveTo(y: frame.width / -2 - 100, duration: 1.0)
        let remove = SKAction.removeFromParent()
        itemBox.run(SKAction.sequence([move, remove]))        
    }
    
[/code]

その後、下記メソッドでitemBox(node)とspaceship(node)が接触した際にitem1をユーザーが取得(addChild(item1))します。

[code]

    func hit(itemBox: SKPhysicsBody, target: SKPhysicsBody) {
        guard let itemBoxNode = itemBox.node else { return }
        guard let targetNode = target.node else { return }
        let itemBoxFunc = ItemBoxFunc()
    
        if target.categoryBitMask == spaceshipCategory {
            itemBoxNode.removeFromParent()
            addChild(item1)
        }
    }
    
[/code]

一応別クラスにスイッチ的な変数を作成して、初期状態はON、itemBox(node)とspaceship(node)が接触した際はOFFにして、OFFの時にはitemBoxを出現させない、の様な仕様を試みたのですが上手くいきませんでした。

追記/item1の宣言コード

【クラス内】

[code]

    var item1: SKSpriteNode!
    
[/code]

【didMove内】

[code]

        self.item1 = SKSpriteNode(imageNamed: "item1")
        self.item1.position = CGPoint(x: frame.width / -2 + 150, y: frame.height / -2 +  150)
        self.item1.size = CGSize(width: 100, height: 100)
        self.item1.zPosition = 1.0
        self.item1.alpha = 0.5
        self.item1.name = "item1"
    
[/code]


CC BY-SA 4.0
2020-05-17T12:53:47.900
66718
2020-05-17T20:11:06.933
2020-05-17T16:55:49.560
3060
39881
question
swift xcode spritekit
Swift SpriteKit 1度だけメソッドを動作させたい


「一度だけメソッドを動作」させると言うよりも、「item1が重複してしまいエラーが発生」するのを防ぐ、と言うことが主眼であるように解釈しました。

ご提示いただいたコードを見る限り、関連する部分を改善することにより自然と防止できるようにする、と言った上手い書き方はなさそうなので、

  * `item1`が何かの子ノードになっていたら実行しないようにする

と言うロジックを入れるのが簡単ではないかと思います。

`hit(itemBox:target:)`内のif文を次のように変更してみてはいかがでしょうか。

[code]

            if target.categoryBitMask == spaceshipCategory && item1.parent == nil {
                itemBoxNode.removeFromParent()
                addChild(item1)
            }
    
[/code]

`item1.parent ==
nil`と言う条件は、「`item1`に親ノードがいない」つまり「`item1`をどこかの親ノードに`addChild`できる」と言うことを表しますので、それが成り立つときにだけ`{
}`内が実行されることになります。


CC BY-SA 4.0
2020-05-17T20:11:06.933
66729
2020-05-17T20:11:06.933
13972
66718
answer