Omer Harel
Omer Harel

Reputation: 283

TVOS : detecting touches with press began and functions (Swift Spritekit)

im trying to define touches in TVOS with press began but its not working.

i want to connect 3 functions

Game scene TVOS:

 func StartGameRecognizer(gesture: UITapGestureRecognizer) {

        if isGameOver {
        } else if !isStarted {
            start()
        } else {
            hero.flip()
        }

    }

 func playPauseMusicRecognizer(gesture: UITapGestureRecognizer) {

            let onoroff = UserDefaults.standard.bool(forKey: "onoroff")

            if !onoroff { //playing is false
                Singleton.sharedInstance().pauseBackgroundMusic()
                SoundOnOff.texture = SKTexture(imageNamed:"Sound-off.png")
                UserDefaults.standard.set(true, forKey: "onoroff")
            }
            else {
                Singleton.sharedInstance().resumeBackgroundMusic()
                SoundOnOff.texture = SKTexture(imageNamed:"Sound-on.png")
                UserDefaults.standard.set(false, forKey: "onoroff")
            }
        }

func RestartGameRecognizer(gesture: UISwipeGestureRecognizer){
    print("RestartGame")
    //Re-open GameScene

    GameViewController().TitleGameOver.isHidden = true
    GameViewController().RestartButton.isHidden = true
    GameViewController().scoreTextLabel.isHidden = true
    GameViewController().highscoreTextLabel.isHidden = true
    GameViewController().ScoreBoardTV.isHidden = true
    GameViewController().Score.isHidden = true
    GameViewController().HighScore.isHidden = true
    GameViewController().NewhighscoreTextLabel.isHidden = true
    GameViewController().HomeButton.isHidden = true
    // Singleton.sharedInstance().resumeSoundEffectClickedButton()
    GameViewController().gameDidStart()


}

GameViewControllerTVOS:

 override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {
    for press in presses {
        switch press.type {
        case .upArrow:
            print("Up Arrow")
        case .downArrow:
            print("Down arrow")
        case .leftArrow:
            print("Left arrow")
        case .rightArrow:
            print("Right arrow")
        case .select:
            print("Select")
        case .menu:
            print("Menu")
        case .playPause:
            print("Play/Pause")

        default:
        print("")
        }
    }
}

I need example or hint to write the code right.

Update:

GameSceneTvOS:

    override func didMove(to view: SKView) {

        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(GameSceneTVOS.StartGameRecognizer(gesture:)))
        tapGesture.allowedPressTypes = [NSNumber(value: UIPressType.Select.rawValue)]
        view.addGestureRecognizer(tapGesture)

        let tapGesture1 = UITapGestureRecognizer(target: self, action: #selector(GameSceneTVOS.PlaypauseMusicRecognizer(gesture:)))
        tapGesture1.allowedPressTypes = [NSNumber(value: UIPressType.PlayPause.rawValue)]
        view.addGestureRecognizer(tapGesture1)

        let swipeUp = UISwipeGestureRecognizer(target: self, action: #selector(GameSceneTVOS.RestartGameRecognizer(gesture:)))
        swipeUp.direction = UISwipeGestureRecognizerDirection.up
        self.view?.addGestureRecognizer(swipeUp)
}

**Functions :**

func StartGameRecognizer(gesture: UITapGestureRecognizer) {
        print("StartGame")

            if isGameOver {
                } else if !isStarted {
                    start()
                } else {
                    hero.flip()
                }

            }

    func PlaypauseMusicRecognizer(gesture: UITapGestureRecognizer) {
        print("PlaypauseMusic")


       let onoroff = UserDefaults.standard.bool(forKey: "onoroff")

        if !onoroff { //playing is false
            Singleton.sharedInstance().pauseBackgroundMusic()
            SoundOnOff.texture = SKTexture(imageNamed:"Sound-off.png")
            UserDefaults.standard.set(true, forKey: "onoroff")
        }
        else {
            Singleton.sharedInstance().resumeBackgroundMusic()
            SoundOnOff.texture = SKTexture(imageNamed:"Sound-on.png")
            UserDefaults.standard.set(false, forKey: "onoroff")
        }
    }


    func RestartGameRecognizer(gesture: UISwipeGestureRecognizer){
        print("RestartGame")
        //Re-open GameScene

        GameViewController().TitleGameOver.isHidden = true
        GameViewController().RestartButton.isHidden = true
        GameViewController().scoreTextLabel.isHidden = true
        GameViewController().highscoreTextLabel.isHidden = true
        GameViewController().ScoreBoardTV.isHidden = true
        GameViewController().Score.isHidden = true
        GameViewController().HighScore.isHidden = true
        GameViewController().NewhighscoreTextLabel.isHidden = true
        GameViewController().HomeButton.isHidden = true
        // Singleton.sharedInstance().resumeSoundEffectClickedButton()
        GameViewController().gameDidStart()


    }

enter image description here

Upvotes: 0

Views: 845

Answers (2)

Michael N
Michael N

Reputation: 559

Do not use UISwipeGestureRecognizer or UITapGestureRecognizer gestures.

Also, make sure you disable any touch logic if you're using the remote. Touching the tvOS remote will trigger touches began.

Utilize pressesBegan to invoke the function in the dPadUp, dpadDown, aAction, bAction, etc.

extension GameViewController {
    
    // MARK: - tvOS Controls -

    override func pressesBegan(_ presses: Set<UIPress>, with event: UIPressesEvent?) {

        var didHandleEvent = false
        
        for press in presses {
            
            #if os(tvOS)
            
            // tvOS
            
            if press.type == .select {
                
                // click touch pad
                
                print("select")
                
                self.aAction()
                
            } else if press.type == .menu {
                
                // menu button
                
                print("menu")
                
            } else if press.type == .playPause {
                
                // play pause
                
                self.bAction()
                
                print("playPause")
                
            } else if press.type == .upArrow {
                
                // upArrow
                
                print("upArrow")
                
                self.dPadUp()
                
            } else if press.type == .leftArrow {
                
                // leftArrow
                
                print("leftArrow")
                
                self.dPadLeft()
                
            } else if press.type == .downArrow {
                
                // downArrow
                
                print("downArrow")
                
                self.dPadDown()
                
            } else if press.type == .rightArrow {
                
                // rightArrow
                
                print("rightArrow")
                
                self.dPadRight()
                
            }
                
            if #available(tvOS 14.3, *) {

                if press.type == .pageUp {
                    
                    // pageUp
                    
                    print("pageUp")
                    
                } else if press.type == .pageDown {
                    
                    // pageDown
                    
                    print("pageDown")
                    
                }
                
            }
            
            #endif

        }

        if didHandleEvent == false {
            
            // Didn't handle this key press, so pass the event to the next responder.

            super.pressesBegan(presses, with: event)

        }

    }
    
    // MARK: - Keyboard -
    
    @objc func dPadUp() {
        
        print("up")
                
    }
    
    @objc func dPadLeft() {
        
        print("left")
        
    }
    
    @objc func dPadRight() {
        
        print("right")
        
    }
    
    @objc func dPadDown() {
        
        print("down")
                        
    }
    
    @objc func idleButton() {
        
        print("idle")
                
    }
    
    @objc func aAction() {
        
        print("aAction")
                
    }
    
    @objc func xAction() {
        
        print("xAction")
                
    }
    
    @objc func yAction() {
        
        print("yAction")
                
    }

    @objc func bAction() {
        
        print("bAction")
                        
    }
        
}

Upvotes: 0

crashoverride777
crashoverride777

Reputation: 10674

You code has some problems.

1) This code is wrong in the restartGame method.

  GameViewController().TitleGameOver.isHidden = true
  GameViewController().RestartButton.isHidden = true
  ...

You are creating a new instance of GameViewController on every line, you are not referencing the current game view controller.

2) You should not be using your GameViewController to create your UI, you should be doing it directly in the relevant SKScenes using only SpriteKit APIs (SKLabelNodes, SKSpriteNodes, SKNodes etc). Using UIKit in SpriteKit, except in some occasions, is bad practice.

3) You should be using TouchesBegan, TouchesMoved etc directly in the SKScenes to get touch input, dont use the GameViewController method. They fill fire just like they do when you are on iOS.

You can also create gesture recognizers in your SKScene to get button presses from the SiriRemote.

/// Pressed, not tapped, main touch pad
let pressedMain = UITapGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
pressedMain.allowedPressTypes = [NSNumber(value: UIPressType.select.rawValue)]
view?.addGestureRecognizer(pressedMain)

/// Pressed play pause button
let pressedPlayPause = UITapGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
pressedPlayPause.allowedPressTypes = [NSNumber(value: UIPressType.playPause.rawValue)]
view?.addGestureRecognizer(pressedPlayPause)

 /// Pressed menu button
let pressedMenu = UITapGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
pressedMenu.allowedPressTypes = [NSNumber(value: UIPressType.menu.rawValue)]
view?.addGestureRecognizer(pressedMenu)

You can also use swipe gesture recognizers if you want

let rightSwipe = UISwipeGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
rightSwipe.direction = .right
view?.addGestureRecognizer(rightSwipe)

let leftSwipe = UISwipeGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
leftSwipe.direction = .left
view?.addGestureRecognizer(leftSwipe)

let upSwipe = UISwipeGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
upSwipe.direction = .up
view?.addGestureRecognizer(upSwipe)

let downSwipe = UISwipeGestureRecognizer(target: self, action: #selector(SOMEMETHOD))
downSwipe.direction = .down
view?.addGestureRecognizer(downSwipe)

If you are using gesture recognisers, remember they are added to the GameViewController (view?.addGesture...) so its good practice to remove them when you add either new ones, or if you change to a new scene where you might need different ones.

Call this code when you exit a scene or add new gesture recognizers.

 for gestureRecognizer in view?.gestureRecognizers ?? [] {
        view?.removeGestureRecognizer(gestureRecognizer)
    }

If you are looking for fully fledged micro gamepad support than you will need to watch some tutorials about the gameController framework.

4) Try putting your string keys like the ones for UserDefaults in some property.

 enum Key: String {
     case onoroff
 }

and than use it like so

 UserDefaults.standard.set(true, forKey: Key.onoroff.rawValue)

to avoid making typos.

5) You should be following the Swift conventions consistently, some of your methods and properties start with capital letters but they shouldn't.

I would advise that you restructure your code and not continue with this approach of trying to use the GameViewController for all this. It should be all done directly in the relevant SKScene.

EDIT. I think you are calling the selector wrong, try this. When your function has a parameter you would use this (_:), you are trying to use (gesture:). Try this instead.

 ... action: #selector(startGameRecognizer(_:))

Hope this helps

Upvotes: 3

Related Questions