在哪里调用 NotificationCenter.default.addObserver() ?在我的 Xcode 游戏项目中

Where to call NotificationCenter.default.addObserver() ? in my Xcode Game Project

提问人: 提问时间:11/7/2022 更新时间:3/7/2023 访问量:133

问:

在哪里打电话?在我的 Xcode 游戏项目中NotificationCenter.default.addObserver()

我成功地从我的 调用了以下内容,但是当我打开/关闭游戏手柄时,我的选择器没有被调用。func application (AppDelegate)

class GameScene: SKScene {
    
    func ObserveForGameControllers() {
        
    //  print("ObserveForGameControllers")
        
        NotificationCenter.default.addObserver(
                    self,
                    selector: #selector(connectControllers),
                    name: NSNotification.Name.GCControllerDidConnect,
                    object: nil)
        
        NotificationCenter.default.addObserver(
                    self,
                    selector: #selector(disconnectControllers),
                    name: NSNotification.Name.GCControllerDidDisconnect,
                    object: nil)
        
    }   // ObserveForGameControllers

}

我的选择器如下所示:

@objc func connectControllers() {}
@objc func disconnectControllers() {}

最后一件事:

这是我项目中的游戏手柄设置

看来我真的需要一些建议。

欣赏它。

编辑

我一直在与一位非常有才华的 jrturton 联系,试图找出为什么我无法检测到上面记录的游戏手柄的存在。

他要求更完整地介绍我的 Swift 代码。我最初想到的是Dropbox,但他要求进行此编辑。所以这里是:

我从一个 iOS 游戏项目开始,它向我展示了 , , + 。AppDelegateGameSceneGameViewControllerStoryboard

我已经在上面介绍了,根据 jrturton 的建议,它现在被简化为基本上是空的标准,例如:AppDelegateAppDelegatefunc

func application(_ application: UIApplication,
                 didFinishLaunchingWithOptions
                 launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

    // currently empty

}

接下来,..GameScene

import SwiftUI
import WebKit
import SpriteKit
import GameplayKit
import GameController


class GameScene: SKScene {
    
    override func sceneDidLoad() {
        
        super.sceneDidLoad()
        
    //  print("sceneDidLoad")
        
        ObserveForGameControllers()
        
    }   // sceneDidLoad


    func ObserveForGameControllers() {
        
    //  print("ObserveForGameControllers")
        
        NotificationCenter.default.addObserver(
                    self,
                    selector: #selector(connectControllers),
                    name: NSNotification.Name.GCControllerDidConnect,
                    object: nil)
        
        NotificationCenter.default.addObserver(
                    self,
                    selector: #selector(disconnectControllers),
                    name: NSNotification.Name.GCControllerDidDisconnect,
                    object: nil)
        
    }   // ObserveForGameControllers
    
    
    @objc func connectControllers() {
        
    //  print("CONNECT")

        self.isPaused = false
        
        var indexNumber = 0
        
        for controller in GCController.controllers() {
            
            if controller.extendedGamepad != nil {
                controller.playerIndex = GCControllerPlayerIndex.init(rawValue: indexNumber)!
                
                indexNumber += 1
                setupControllerControls(controller: controller)
            }
            
        }
        
    }   // connectControllers

    
    @objc func disconnectControllers() {
        
    //  print("DIS-CONNECT")

        self.isPaused = true
        
    }   // disconnectControllers
    

    func setupControllerControls(controller: GCController) {
        
        controller.extendedGamepad?.valueChangedHandler = {
            (gamepad: GCExtendedGamepad, element: GCControllerElement) in
            
            self.controllerInputDetected(gamepad: gamepad,
                                         element: element,
                                         index: controller.playerIndex.rawValue)
        }
        
    }   // setupControllerControls


    func controllerInputDetected(gamepad: GCExtendedGamepad,
                                 element: GCControllerElement,
                                 index: Int) {
        
        // A-Button
        if (gamepad.buttonA == element)
        {
            if (gamepad.buttonA.value != 0)
            {
                // These print(..) statements will be replaced later
                // by code to access my Javascript methods.
                print("movePaddleDown")
            }
        }
        
        // B-Button
        else if (gamepad.buttonB == element)
        {
            if (gamepad.buttonB.value != 0)
            {
                print("movePaddleRight")
            }
        }
        
        // Y-Button
        else if (gamepad.buttonY == element)
        {
            if (gamepad.buttonY.value != 0)
            {
                print("movePaddleUp")
            }
        }
        
        // X-Button
        else if (gamepad.buttonX == element)
        {
            if (gamepad.buttonX.value != 0)
            {
                print("movePaddleLeft")
            }
        }
        
        // leftShoulder
        else if (gamepad.leftShoulder == element)
        {
            if (gamepad.leftShoulder.value != 0)
            {
                print("cyclePages")
            }
        }
        
        // rightShoulder
        else if (gamepad.rightShoulder == element)
        {
            if (gamepad.rightShoulder.value != 0)
            {
                print("newGame")
            }
        }
        
        // leftTrigger
        else if (gamepad.leftTrigger == element)
        {
            if (gamepad.leftTrigger.value != 0)
            {
                print("pauseGame")
            }
        }
        
        // rightTrigger
        else if (gamepad.rightTrigger == element)
        {
            if (gamepad.rightTrigger.value != 0)
            {
                print("resumeGame")
            }
        }
        
        // Left Thumbstick
        else if (gamepad.leftThumbstick == element)
        {
            if (gamepad.leftThumbstick.xAxis.value > 0)
            {
                print("movePaddleRight")
            }
            else if (gamepad.leftThumbstick.xAxis.value < 0)
            {
                print("movePaddleLeft")
            }
            else if (gamepad.leftThumbstick.xAxis.value == 0)
            {
                print("decreaseSpeed")
            }
            else if (gamepad.leftThumbstick.yAxis.value > 0)
            {
                print("movePaddleDown")
            }
            else if (gamepad.leftThumbstick.yAxis.value < 0)
            {
                print("movePaddleUp")
            }
            else if (gamepad.leftThumbstick.yAxis.value == 0)
            {
                print("decreaseSpeed")
            }
        }
        
        // Right Thumbstick
        if (gamepad.rightThumbstick == element)
        {
            if (gamepad.rightThumbstick.xAxis.value > 0)
            {
                print("movePaddleRight")
            }
            else if (gamepad.rightThumbstick.xAxis.value < 0)
            {
                print("movePaddleLeft")
            }
            else if (gamepad.rightThumbstick.xAxis.value == 0)
            {
                print("decreaseSpeed")
            }
            else if (gamepad.rightThumbstick.yAxis.value > 0)
            {
                print("movePaddleDown")
            }
            else if (gamepad.rightThumbstick.yAxis.value < 0)
            {
                print("movePaddleUp")
            }
            else if (gamepad.rightThumbstick.yAxis.value == 0)
            {
                print("decreaseSpeed")
            }
        }
        
        // D-Pad
        else if (gamepad.dpad == element)
        {
            if (gamepad.dpad.xAxis.value > 0)
            {
                print("scrollWindowRight")
            }
            else if (gamepad.dpad.xAxis.value < 0)
            {
                print("scrollWindowLeft")
            }
            else if (gamepad.dpad.yAxis.value > 0)
            {
                print("scrollWindowDown")
            }
            else if (gamepad.dpad.yAxis.value < 0)
            {
                print("scrollWindowUp")
            }
        }
        
    }   // controllerInputDetected

}   // class GameScene: SKScene

现在,..GameViewController

import UIKit
import SpriteKit
import GameplayKit
import WebKit


// This is now available across Classes
var theWebView: WKWebView!


class GameViewController: UIViewController, WKNavigationDelegate {
    
    override func loadView() {
        
    //  print("loadView")
        
        let webConfiguration = WKWebViewConfiguration()
        theWebView = WKWebView(frame: .zero, configuration: webConfiguration)
        theWebView.navigationDelegate = self
        view = theWebView
        
    }   // loadView
    
    
    override func viewDidLoad() {
        
        super.viewDidLoad()
        
    //  print("viewDidLoad")
               
        loadURL(webAddress: "https://www.lovesongforever.com/firstgame")
        
    }   // viewDidLoad
    
    
    func loadURL(webAddress: String) {
        
        let theURL = URL(string: webAddress)
        let theRequest = URLRequest(url: theURL!)
        theWebView.load(theRequest)
        theWebView.allowsBackForwardNavigationGestures = false

    }   // loadURL

    
    override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
        
        if UIDevice.current.userInterfaceIdiom == .phone {
            return .allButUpsideDown
        }
        else {
            return .all
        }
        
    }   // supportedInterfaceOrientations

    
    override var prefersStatusBarHidden: Bool {
        
        return true
        
    }   // prefersStatusBarHidden
    
}   // class GameViewController

请注意,当我运行我的 iOS 应用程序时,由于上面的覆盖,它在模拟器中显示以下内容:loadView()

模拟器演示

但是,仅此而已,因为按下游戏手柄上的所有按钮会导致检测到我的游戏手柄,正如我取消注释上述所有 print(..) 语句时所证明的那样。特别是,那些在以下领域:

@objc func connectControllers()以及@objc func disconnectControllers()func controllerInputDetected( .. )

所以,希望这就是目前的全部......

Xcode 通知中心

评论

0赞 jrturton 11/7/2022
请出示您拨打电话的代码。应用委托在场景中调用方法似乎有点早ObserveForGameControllers
0赞 11/7/2022
let itsGameScene = GameScene(); itsGameScene.ObserveForGameControllers()
0赞 11/7/2022
FWIW,我同意你的早期评论......但我不知道其他选择。我想到了,但我远不能确定。class GameViewController
0赞 jrturton 11/9/2022
您添加的代码不会加载任何 SKScene,它只是创建并打开一个 Web 视图。您附加的屏幕截图来自网页。您是在制作 SpriteKit 游戏,还是在 iOS 应用程序中包装网页游戏?
0赞 11/10/2022
尝试将网页游戏打包到 iOS 应用中。听起来比从头开始构建游戏要容易得多。我只是不明白为什么在 gameViewController 的 viewDidLoad 中调用 WKWebView 对我的游戏手柄没有反应。我的屏幕截图说它在那里,但对游戏手柄的反应为零

答:

0赞 jrturton 11/7/2022 #1

您正在应用委托中执行此操作:

let itsGameScene = GameScene() 
itsGameScene.ObserveForGameControllers()

您正在创建一个实例,使其侦听通知(添加为观察者)...然后可能会扔掉那个实例。GameSceneself

你的游戏实际上并没有使用 ,也不需要处理游戏控制器,你只需要 .SpriteKitSpriteKitGameController

你根本不需要创建这个场景。观察游戏控制器通知的最佳位置是 in .将场景中的代码(观察方法和与控制器相关的代码)移动到视图控制器中,然后删除场景文件。GameViewControllerviewDidLoad