ECN
ECN

Reputation: 11

SwiftUI not setting a transparent background

I am trying to set a transparent background in my gamescene so when it is displayed in gameview a different background is shown.

here is my gamescene code:

class Gamescene: SKScene, ObservableObject, SKPhysicsContactDelegate {
    weak var gameDelegate: GamesceneDelegate?
    
    
    
    // score functions
    private var score: Int = 0
    private var scoreLabel: SKLabelNode!
    
    
    override init(size: CGSize) {
            super.init(size: size)
        self.backgroundColor = .clear //  background
            self.zPosition = -1
            self.physicsWorld.contactDelegate = self // Setup physics contact delegate
        print("Gamescene initialized with size: \(size)")
            // Additional setup code as needed
        }
        
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
    
    override func didMove(to view: SKView) {
        super.didMove(to: view)
        view.allowsTransparency = true
        backgroundColor = .clear //controls background
        self.zPosition = -1
        setupScene()
        print("Gamescene did move to view")
        
    }
    
    private func setupScene() {
        
        print("Gamescene setup complete")
        }

This is my gamescene code:

import SwiftUI
import SpriteKit

struct GameView: View {
    @StateObject var scene: Gamescene
    let backgroundNames = ["background1", "background2", "background3", "background4", "background5"]
    @State private var offset: CGFloat = 0

    let animationDuration: Double = 10.0 // Adjust animation duration as needed

    init() {
        let gameScene = Gamescene(size: CGSize(width: 400, height: 700))
        gameScene.scaleMode = .fill
        _scene = StateObject(wrappedValue: gameScene)
        print("GameView initialized")
    }

    var body: some View {
        ZStack {
            
            // Sliding background
            GeometryReader { geometry in
                HStack(spacing: 0) {
                    ForEach(0..<(backgroundNames.count * 2), id: \.self) { index in
                        Image(backgroundNames[index % backgroundNames.count])
                            .resizable()
                            .frame(width: 1000, height: geometry.size.height)
                            .scaledToFill()
                    }
                }
                .frame(width: 1000 * CGFloat(backgroundNames.count * 2), height: geometry.size.height, alignment: .leading)
                .offset(x: offset)
                .onAppear {
                    startAnimation(totalWidth: 1000 * CGFloat(backgroundNames.count))
                    print("GameView appeared")
                }
            }

            // SpriteView containing the game scene
            SpriteView(scene: scene)
                .frame(width: 400, height: 700)
                .background(Color.clear)
                .edgesIgnoringSafeArea(.all)
                .onAppear {
                    if let skView = scene.view {
                    skView.allowsTransparency = true
                        print("SKView allows transparency: \(skView.allowsTransparency)")
                    }
            }
        }
    }

    func startAnimation(totalWidth: CGFloat) {
        offset = 0
        withAnimation(.linear(duration: animationDuration).repeatForever(autoreverses: false)) {
            offset = -totalWidth
        }
    }
}

struct Gameview_Previews: PreviewProvider {
    static var previews: some View {
        GameView()
    }
}

The gamescene background should be clear so in gameview background1, background2, ... are shown. However even though it is set to clear the background is still showing as black

Here I have changed the gamescene to have a green background

override func didMove(to view: SKView) {
        super.didMove(to: view)
        view.allowsTransparency = true
        backgroundColor = .green //controls background
        self.zPosition = -1
        setupScene()
        print("Gamescene did move to view")
        
    }
    

and the background comes up green on top of background1, background2 etc in gameview but when i set to clear its just black and I dont know why. I have also tried changing the Z positions but that doesnt help either

Upvotes: 0

Views: 69

Answers (1)

Fault
Fault

Reputation: 1294

for a transparent background SKScene, you should do two things.

add the appropriate option to your SwiftUI SpriteView:

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

set the background to .clear in your SKScene

override func didMove(to view: SKView) {
    self.backgroundColor = .clear
}

as far as i know calling view.allowsTransparency = true on your SKView doesn't seem to affect the outcome one way or the other.

Upvotes: 0

Related Questions