

どなたか、よろしくお願いいたします！

missile（Node）をtouchesBeganで呼び出しています。  
didBeginでmissile（Node）が接触したasteroid（Node）を消滅させる事が目的です。

問題なく、１度目のtouchesBeganは作動して、missile（Node）が発射されるのですが、２度目以降のtouchesBeganが作動しません。原因がわからず大変困っております。

また、上記のご回答のみで十分なのですが、もう一つ解決して頂きたい問題がございますので、もしお分かりになる方がいらっしゃいましたらご教授くださいませ。

touchesBegan内でmissile（Node）の発射を宣言しており、その発射間隔を今回は0.2秒に設定しております。  
この状態で実行すると、0.2秒間以内に２回以上のタッチをするとエラーが出てしまいます。  
こちらも原因が不明でございます。

どうかよろしくお願いいたします。

[code]

    import SpriteKit
    import GameplayKit
    
    class GameScene: SKScene, SKPhysicsContactDelegate {
    
        var spaceship:SKSpriteNode! = SKSpriteNode(imageNamed: "spaceship") 
        var button : SKSpriteNode! 
        var missile: SKSpriteNode = SKSpriteNode(imageNamed: "missile") 
    
        let spaceshipCategory : UInt32 = 0b0001
        let missileCategory : UInt32 = 0b0010
        let asteroidCategory  : UInt32 = 0b0100
    
        var timar: Timer?
    
        func DegreeToRadian(Degree : Double!) -> CGFloat{
            return CGFloat(Degree) / CGFloat(180.0 * M_1_PI)
        }
    
        override func didMove(to view: SKView) {
    
            physicsWorld.gravity = CGVector(dx: 0, dy: 0)
            physicsWorld.contactDelegate = self
    
            self.backgroundColor = UIColor.black 
    
            self.spaceship.alpha = 1 
            self.spaceship.position = CGPoint(x: view.frame.width / -2 + 100, y: view.frame.height / -2 + 100) 
            self.spaceship.size = CGSize(width: 150, height: 150) 
            self.spaceship.zRotation = DegreeToRadian(Degree: 0) 
            self.spaceship.isUserInteractionEnabled = false 
            self.spaceship.physicsBody = SKPhysicsBody(circleOfRadius: self.spaceship.frame.width * 0.1) 
            self.spaceship.physicsBody?.categoryBitMask = spaceshipCategory
            self.spaceship.physicsBody?.collisionBitMask = spaceshipCategory | missileCategory | asteroidCategory
            self.spaceship.physicsBody?.contactTestBitMask = asteroidCategory
            self.addChild(self.spaceship) //宇宙船didMove
    
    
            self.button = self.childNode(withName: "button") as? SKSpriteNode 
            if let button = self.button {
                button.name = "button" 
                button.alpha = 0.0 
                button.run(SKAction.fadeIn(withDuration: 2.0)) 
    
            }
    
    
            timar = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { _ in
                self.addasteroid()
            })
    
              }
    
    
        //ここでmissile（Node）を宣言しbutton（Node）をタップした際に実行されるようにしてます。このコードは正常に作動するようです。
        override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            if isPaused { return }
    
            self.missile.physicsBody = SKPhysicsBody(circleOfRadius: self.missile.frame.height / 2 ) 
            self.missile.physicsBody?.categoryBitMask = missileCategory
            self.missile.physicsBody?.collisionBitMask = spaceshipCategory | missileCategory | asteroidCategory
            self.missile.physicsBody?.contactTestBitMask = asteroidCategory
    
    
            if let touch = touches.first { 
                let locatin = touch.location(in: self) 
                    if self.atPoint(locatin).name == "button" { 
    
                       missile.position = CGPoint(x: self.spaceship.position.x , y: self.spaceship.position.y + 10 ) 
                       missile.size = CGSize(width: 75, height: 75) 
                       addChild(missile) 
    
    
                        let topButton = SKAction.moveTo(y: frame.width / 2 - self.spaceship.position.y , duration: 0.2) 
                            let remove = SKAction.removeFromParent() 
                            missile.run(SKAction.sequence([topButton, remove])) 
    
                  }
              }
          }**
    
        override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    
            let touch = touches.first 
            let buttonLocation = touch?.location(in: self)  
            switch self.atPoint(buttonLocation!).name == "button" { 
            case true:
                break
    
            default:
                let location = touches.first!.location(in: self) 
                let action = SKAction.move(to: CGPoint(x: location.x, y:location.y + 20), duration: 0.1) 
                spaceship.run(action) 
            }
    
            }
    
    
        override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        }
    
    
        override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        }
    
    
        override func update(_ currentTime: TimeInterval) {
    
        }
    
    
        func addasteroid() {
    
            let names = ["asteroid1","asteroid2","asteroid3"]
            let index = Int.random(in: 0...2) 
            let name = names[index] 
            let asteroid = SKSpriteNode(imageNamed: name) 
    
            let XHighest: CGFloat = self.frame.width / 2 - spaceship.size.width 
            let XLowest: CGFloat = self.frame.width / -2 + spaceship.size.width 
            let random = CGFloat.random(in: XLowest...XHighest) /
            asteroid.position = CGPoint(x: random, y: frame.width) 
            asteroid.size = CGSize(width: 100, height: 100) 
    
            asteroid.physicsBody = SKPhysicsBody(circleOfRadius: asteroid.frame.width)
            asteroid.physicsBody?.categoryBitMask = asteroidCategory
            asteroid.physicsBody?.collisionBitMask = spaceshipCategory | missileCategory | asteroidCategory
            asteroid.physicsBody?.contactTestBitMask = spaceshipCategory | missileCategory
    
            addChild(asteroid) 
    
            let move = SKAction.moveTo(y: frame.width / -2 - 100, duration: 1.0) 
            let remove = SKAction.removeFromParent()
            asteroid.run(SKAction.sequence([move, remove]))
        }
    
    //ここからのコードが微妙です。
            func didBegin(_ contact: SKPhysicsContact) {
    
                var asteroid: SKPhysicsBody
                var target: SKPhysicsBody
    
                if contact.bodyA.categoryBitMask == asteroidCategory {
                    asteroid = contact.bodyA
                    target = contact.bodyB
    
                } else {
                    asteroid = contact.bodyB
                    target = contact.bodyA
                }
    
                guard let asteroidNode = asteroid.node else { return }
                guard let tagetNode = target.node else { return }
                guard let Bakuhatu = SKEmitterNode(fileNamed: "Bakuhatu") else { return }
                Bakuhatu.position = asteroidNode.position
                addChild(Bakuhatu)
    
                //asteroid（Node）の接触先がmissile（Node）だった場合にasteroid（Node）とmissile（Node）を消滅させたいです。１度目のタップは正常なのですが、１度このアクションを実行すると２度目以降が作動しなくなってしまいます。。
                asteroidNode.removeFromParent()
                if target.categoryBitMask == missileCategory  {
                    tagetNode.removeFromParent()
                }
    
                self.run(SKAction.wait(forDuration: 1.0)) {
                    Bakuhatu.removeFromParent()
                }
    
        }
    }
    
[/code]


CC BY-SA 4.0
2020-05-04T11:24:32.993
66285
2020-05-04T18:31:24.750
2020-05-04T18:31:24.750
39881
39881
question
swift xcode spritekit
Swift SpriteKit　touchesBeganで行うNodeの対消滅