【问题标题】:How can I make background of an SKScene transparent so I can layer in a ZStack?如何使 SKScene 的背景透明,以便在 ZStack 中分层?
【发布时间】:2021-01-11 21:47:10
【问题描述】:

我正在尝试使用 SwiftUI 和 SpriteKit 制作游戏。我希望能够在 ZStack 中布局游戏,并将游戏分层放在背景图像上。为此,我需要使 SKScene 的背景透明。但是当我这样做时,我添加到 SKScene 的节点不再显示。

这是我正在使用的编码:

import SwiftUI
import SpriteKit
import GameplayKit

class GameScene: SKScene {
  
  override func didMove(to view: SKView) {
    
    view.allowsTransparency = true
    self.backgroundColor = .clear
    view.alpha = 0.0
    view.isOpaque = true
    view.backgroundColor = SKColor.clear.withAlphaComponent(0.0)

    
    if let particles = SKEmitterNode(fileNamed: "Mud") {
      particles.position.x = 512
      addChild(particles)
    }
    
  }
  
}


struct ContentView: View {
  
  var scene: SKScene {
    
    let scene = GameScene()
    scene.size = CGSize(width: 300, height: 400)
    scene.scaleMode = .fill
    
    return scene
  }
  
  var body: some View {
    ZStack {
      Image("road")
        .resizable()
        .aspectRatio(contentMode: /*@START_MENU_TOKEN@*/.fill/*@END_MENU_TOKEN@*/)
        .ignoresSafeArea()
      SpriteView(scene: scene)
        .ignoresSafeArea()
        .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
    }
  }
}

SKScene 的背景是透明的,我可以在 ZStack 中看到分层的图像。但是,场景中的其他所有东西也是透明的,所以我根本看不到发射器效果。

我怎样才能使 SKScene 的背景透明?

【问题讨论】:

    标签: sprite-kit swiftui


    【解决方案1】:

    终于用自定义SpriteView解决了。下面的代码使 spritekit 视图实际上具有透明背景。问题似乎是 swiftUI 的声明性质意味着你总是使用他们的 SpriteView (它有黑色背景)。 SKScene 确实是唯一被传递到 SwiftUI 中的东西。

    我认为这解释了为什么视图设置没有 UIKit 的效果。

    解决方案是在主体结构之外创建一个新的 SpriteView,然后在主体结构中使用它来代替标准 SpriteView(scene:scene)。这允许在 init() 中设置 SpriteView.Options 以最终在 SwiftUI 的一些呈现的视图中设置 .allowsTransparency。

    请看下面的代码:

    //  Created by Larry Mcdowell on 9/25/20.
    //
    
    import SwiftUI
    import SpriteKit
    import GameplayKit
    
    class GameScene: SKScene {
        
    
       override func didMove(to view: SKView) {
         
        
            // 1
            self.backgroundColor = .clear
            
            //2
            view.allowsTransparency = true
            
            
            if let particles = SKEmitterNode(fileNamed: "Mud"){
                particles.position.x = 140
                particles.position.y = 200
           
                addChild(particles)
            }
        }
        
    
    }
    
    
    
    struct ContentView: View {
        
        var mySpriteView:SpriteView
      
        init(){
            
            mySpriteView = SpriteView(scene: scene, transition: nil, isPaused: false, preferredFramesPerSecond: 60, options: [.allowsTransparency], shouldRender: {_ in return true})
            
        }
        let scene:GameScene = {
            let scene = GameScene()
            scene.size = CGSize(width: 300, height: 400)
            scene.scaleMode = .fill
            
            return scene
        }()
        
    
        var body: some View {
            
            ZStack {
                
                  Image("road")
                    .resizable()
                    .aspectRatio(contentMode: .fill)
                    .ignoresSafeArea()
       
                mySpriteView
                  .ignoresSafeArea()
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
             
            }
        }
        
    }
    
    struct ContentView_Previews: PreviewProvider {
        static var previews: some View {
            ContentView()
        }
    }
    

    这是一个未雨绸缪的有趣项目!

    【讨论】:

    • 非常感谢!那很完美!谢谢!
    【解决方案2】:

    您只需将场景背景设置为 .clear,并将选项作为参数传递给 SpriteView 以实现透明度。所以对于你的情况,它会是

    SpriteView(scene: scene, options: [.allowsTransparency])
    

    所有的 SKView 修改都可以删除。

    【讨论】:

      【解决方案3】:

      有关实际解决方案,请参阅我在此线程上的最终答案。一旦我发现了自定义 SpriteView,我决定删除我最初包含的解决方法。

      【讨论】:

      • 谢谢你。您的代码绝对是对我的改进!我仍然希望找到一种使 SKScene 透明的方法,但这绝对有帮助。谢谢。
      • 刚刚添加了一种可能的方法。这个链接说 swiftUI HostingController 还不允许改变背景颜色。我以前和这个摔跤过。 developer.apple.com/forums/thread/127707
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-27
      • 1970-01-01
      • 2019-08-15
      • 1970-01-01
      • 1970-01-01
      • 2015-08-06
      • 2011-09-17
      相关资源
      最近更新 更多