Reputation: 283
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()
}
Upvotes: 0
Views: 845
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
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