передайте / поделитесь классом с помощью SpriteView GameScene из представления SwiftUI

#class #swiftui #spriteview

Вопрос:

Я играю со SpriteView, который отлично работает. Однако я не могу понять,как поделиться классом с Spritekit GameScene, который создан в одном из моих представлений. Совместное использование моего класса с другими взглядами работает как заклинание. Но как я могу получить доступ к своему классу gameCenterManager из GameScene spritekit, как мне передать класс ? Я понятия не имею, как это сделать. Я подумывал о создании глобального доступного класса, но это не то, что я хочу.

Цель состоит в том, чтобы иметь возможность отправлять и получать данные из GameScene для обновления местоположения игроков и т. Д. Но сопоставление происходит внутри представления SwiftUI, где также создается класс.

Класс gameCenterManger создается следующим образом;

 struct ContentView: View {
   
    @StateObject var gameCenterManager = GameCenterManager()
    
    var body: some View {

    ...
    etc
 

класс настроен следующим образом :

 class GameCenterManager: NSObject, ObservableObject {

   //lots of stuff going on
   ...

}
 

И является общим для представления GameSceneView, которое создаст SpriteView, вот так :

     Button("Show Sheet") {
            self.showingSheet.toggle()
    }
    .buttonStyle(RoundedRectangleButtonStyle())
    .buttonStyle(ShadowButtonStyle())
    .fullScreenCover(isPresented: $showingSheet, content: { GameSceneView(gameCenterManager:self.gameCenterManager)})
 

Наконец, внутри моего GameSceneView настроен GameScene для SpriteView.

 struct GameSceneView: View {
    
    var gameCenterManager: GameCenterManager
    @Environment(.presentationMode) var presentationMode
    
    var scene: SKScene {
        let scene = GameScene()
        scene.size = CGSize(width: UIScreen.main.bounds.size.width , height: UIScreen.main.bounds.size.height)
        scene.scaleMode = .fill

        return scene
    }

    var body: some View {
        
        Button("Dismiss") {
            self.presentationMode.wrappedValue.dismiss()

        }
        
        Button("send data") {
            gameCenterManager.increment()
        }
        

        SpriteView(scene: scene )
            .frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height - 200 )
            .ignoresSafeArea()
            .overlay(ImageOverlay(), alignment: .bottomTrailing)
            
    }
    
}
 

Ответ №1:

Возможно, другие хотят сделать то же самое? Вот ниже приведен ответ в фрагментах кода

GameCenterManager-это класс, к которому я хочу получить доступ во всех представлениях и сценах

В главном окне:

    @main    
   struct gameTestApp: App {
        
        @StateObject var gameCenterManager = GameCenterManager()
        
        var body: some Scene {
            WindowGroup {
                ContentView().environmentObject(gameCenterManager)
            }
        }
    }
 

В представлении Contentview добавить :

 @EnvironmentObject var gameCenterManager:GameCenterManager
 

И где я перейду к GameSceneView внутри Contentview, который загрузит мой SKScene

     Button("Show Sheet") {
            self.showingSheet.toggle()
    }
    .buttonStyle(RoundedRectangleButtonStyle())
    .buttonStyle(ShadowButtonStyle())
    
    .fullScreenCover(isPresented: $showingSheet, content: { GameSceneView()})
 

Затем в GameSceneView добавьте:

 @EnvironmentObject var gameCenterManager:GameCenterManager
 

и где мы загружаем SKScene:

 var scene: SKScene {
        let scene = GameScene()
        scene.size = CGSize(width: UIScreen.main.bounds.size.width , height: UIScreen.main.bounds.size.height)
        scene.scaleMode = .fill
        scene.gameCenterManager = gameCenterManager

        return scene
    }
 

Затем, наконец, в самой GameScene добавьте:

 var gameCenterManager: GameCenterManager?