提问人: 提问时间:11/7/2022 更新时间:3/7/2023 访问量:133
在哪里调用 NotificationCenter.default.addObserver() ?在我的 Xcode 游戏项目中
Where to call NotificationCenter.default.addObserver() ? in my Xcode Game Project
问:
在哪里打电话?在我的 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 游戏项目开始,它向我展示了 , , + 。AppDelegate
GameScene
GameViewController
Storyboard
我已经在上面介绍了,根据 jrturton 的建议,它现在被简化为基本上是空的标准,例如:AppDelegate
AppDelegate
func
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( .. )
所以,希望这就是目前的全部......
答:
您正在应用委托中执行此操作:
let itsGameScene = GameScene()
itsGameScene.ObserveForGameControllers()
您正在创建一个实例,使其侦听通知(添加为观察者)...然后可能会扔掉那个实例。GameScene
self
你的游戏实际上并没有使用 ,也不需要处理游戏控制器,你只需要 .SpriteKit
SpriteKit
GameController
你根本不需要创建这个场景。观察游戏控制器通知的最佳位置是 in .将场景中的代码(观察方法和与控制器相关的代码)移动到视图控制器中,然后删除场景文件。GameViewController
viewDidLoad
评论
ObserveForGameControllers
let itsGameScene = GameScene();
itsGameScene.ObserveForGameControllers()
class GameViewController