2

I am working on a simple game to learn the new functionality of SwiftUI with SpriteKit in Xcode 12. When a user touches the SKScene touchesBegan() everything works as expected. When a user touches the Circle() gesture(DragGesture()), I call the same function, but nothing shows. I can tell from the logs that the function showFragments(location:) is getting called, but nothing shows on screen. Any ideas?

Here is the code:

import SpriteKit
import SwiftUI


struct ContentView: View {
    
    var scene: GameScene {
        let scene = GameScene()
        scene.size = CGSize(width: 350, height: 600)
        scene.scaleMode = .fill
        scene.backgroundColor = .white
        return scene
    }
    var body: some View {
        ZStack {
            SpriteView(scene: scene)
                .frame(width: 350, height: 600)
                .edgesIgnoringSafeArea(.all)
            
            Circle()
                .fill(Color.blue)
                .frame(width: 50, height: 50)
                .gesture(
                    DragGesture(minimumDistance: 0.0)
                        .onChanged({ _ in
                            self.scene.showFragments(location: CGPoint(x: 150, y: 300))
                        })
                )
        }
    }
}

class GameScene: SKScene {
    override func didMove(to view: SKView) {
        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.showFragments(location: CGPoint(x: 150, y: 300))
    }
    
    public func showFragments(location: CGPoint) {
        
        var i: Int = 0
        while i <= 3 {
            i += 1
            let fragment = SKSpriteNode(texture: SKTexture(imageNamed: "Brown Armor Fragment"))
            fragment.position = location
            print ("fragment \(i): \(fragment.position)")
            let wait = SKAction.wait(forDuration: 1)
            let remove = SKAction.run({() in fragment.removeFromParent() })
            
            
            fragment.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Brown Armor Fragment"), alphaThreshold: 0.1, size: CGSize(width: 8, height: 6.5))
            self.addChild(fragment)
            let vx = Double.random(in: -1...1)
            fragment.physicsBody?.applyImpulse(CGVector(dx: vx, dy: 0))
            fragment.run(SKAction.sequence([wait, remove]))
        }
    }
}

1 Answer 1

2

You defined computable property for scene, so it creates different scene for circle gesture.

The solution is to use once-defined scene (tested with Xcode 12 / iOS 14). Use the following expression for scene:

struct ContentView: View {

    let scene: GameScene = {
        let scene = GameScene()
        scene.size = CGSize(width: 350, height: 600)
        scene.scaleMode = .fill
        scene.backgroundColor = .white
        return scene
    }()

    // ... other code

}
Sign up to request clarification or add additional context in comments.

1 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.