About the screen transition using Segue in SKScene in Xcode(Swift)

Asked 2 years ago, Updated 2 years ago, 87 views

<Purpose>
I want the GameScene to be displayed as a present in the ViewController, and I want the GameScene to use the original ViewController Segue to display the next View in order to display the score in the next View.
<Problems>
The build also works fine, but when GameScene is GameOver, I generate a button and try to transition by Segue with that button, but it doesn't.

ViewControllerB.swift

class ViewControllerB:UIViewController{
    override func viewDidAppear(_animated:Bool){

        super.viewDidLoad()
        letscene=GameScene()
        let view=self.view as!SKView

        view.showsFPS=true
        view.showsNodeCount=true

        scene.size=view.frame.size

        view.presentScene(scene)
    }   
}

GameScene.swift

class GameScene:SKScene, SKPhysicsContactDelegate{

    varbowl —SKSpriteNode?

    var timer —Timer?

    var lowestShape —SKShapeNode?

    varscore = 0
    varscoreLabel—SKLabelNode?
    varscoreList= [100, 200, 300, 500, 800, 1000, 1500]
    var viewController:UIViewController?

    override func DidMove (to view:SKView) {

        self.physicsWorld.gravity=CGVector (dx: 0.0, dy: -2.0)
        self.physicsWorld.contactDelegate=self

        let background=SKSpriteNode(imageNamed: "background")
        background.position = CGPoint (x:self.size.width*0.5, y:self.size.height*0.5)
        background.size=self.size
        self.addChild(background)

        let lowestShape=SKShapeNode(rectOf:CGSize(width:self.size.width*3, height:10))
        lowestShape.position = CGPoint (x:self.size.width*0.5, y:-10)

        letphysicsBody = SKPhysicsBody (rectangleOf:lowestShape.frame.size)
        physicsBody.isDynamic=false
        physicsBody.contactTestBitMask = 0x1<<1
        lowestShape.physicsBody=physicsBody

        self.addChild(lowestShape)
        self.lowestShape =lowestShape

        let bowlTexture=SKTexture(imageName: "bowl")
        let bowl = SKSpriteNode (texture: bowlTexture)
        bowl.position = CGPoint (x:self.size.width*0.5, y:100)
        bowl.size = CGSize (width: bowlTexture.size().width*0.5, height: bowlTexture.size().height*0.5)
        bowl.physicsBody = SKPhysicsBody (texture: bowlTexture, size: bowl.size)
        bowl.physicsBody?isDynamic=false
        self.bowl = bowl
        self.addChild(bowl)

        varscoreLabel=SKLabelNode(fontNamed: "Helvetica")
        scoreLabel.position = CGPoint (x:self.size.width*0.92, y:self.size.height*0.78)
        scoreLabel.text=" "0"
        scoreLabel.fontSize=32
        scoreLabel.horizontalAlignmentMode=SKLabelHorizontalAlignmentMode.right
        scoreLabel.fontColor=UIColor.green
        self.addChild(scoreLabel)
        self.scoreLabel=scoreLabel

        self.fallNagoyaSpecialty()

        self.timer = Timer.scheduledTimer (timeInterval:3, target:self, selector:#selector (fallNagoyoSpecialty), userInfo:nil, repeat:true)
    }

    @objc func fallNagoyaSpecialty(){
        let index = Int(arc4 random_uniform(7))
        let texture=SKTexture(imageNamed:"\"(index)")
        let sprite=SKSpriteNode(texture:texture)
        sprite.position = CGPoint (x:self.size.width*0.5, y:self.size.height)
        sprite.size = CGSize (width:texture.size().width*0.5, height:texture.size().height*0.5)
        sprite.physicsBody=SKPhysicsBody(texture:texture, size:sprite.size)
        sprite.physicsBody?.contactTestBitMask = 0x1<<1

        self.addChild(sprite)

        self.score+=self.scoreList [index]
        self.scoreLabel?.text=" \\(self.score)"
    }

    override functouchesBegan(_touches:Set<UITouch>, with event:UIEvent?){
        iflet touch=touches.first{
            let location = touch.location(in:self)
            let action = SKAction.move (to: CGPoint (x: location.x, y:100), duration: 0.2)
            self.bowl?.run(action)
        }
    }

    override functouchesMoved(_touches:Set<UITouch>, with event:UIEvent?) {
        iflet touch=touches.first{
            let location = touch.location(in:self)
            let action = SKAction.move (to: CGPoint (x: location.x, y:100), duration: 0.2)
            self.bowl?.run(action)
        }
    }

    func DidBegin(_contact:SKPhysicsContact){
        if contact.bodyA.node==self.lowestShape||contact.bodyB.node==self.lowestShape{
            let sprite=SKSpriteNode(imageNamed: "gameover")
            sprite.position = CGPoint (x:self.size.width*0.5, y:self.size.height*0.5)
            self.addChild(sprite)

            self.isPaused=true
            self.timer?.invalidate()
            haveScore()
            let myButton=UIButton()
            myButton.frame = CGRect (x:0, y:0, width:200, height:40)
            myButton.backgroundColor=UIColor.red
            myButton.setTitle("Next", for:UIControl.State.normal)
            myButton.setTitleColor (UICol.white, for:UIControl.State.normal)
            myButton.layer.cornerRadius=20.0
            myButton.layer.position=CGPoint (x:self.view!.frame.width/2, y:200.0)
            myButton.addTarget(self, action:#selector(self.next(sender:))), for:.touchUpInside)
            self.view!.addSubview(myButton)     
        }
    }
    funhaveScore(){
        let appDelegate=UIApplication.shared.delegate as!AppDelegate
        appDelegate.message=score
    }

    @objc func next (sender: UIButton) {

        self.viewController?.performSegue(withIdentifier: "toFinish", sender:nil)
    }

}

swift4 spritekit

2022-09-30 17:36

1 Answers

The reason for the 点problem は is that the GameScene class property viewController has no reference to any instance of the UIViewController class.viewController has an optional type, so the default value is .
Within implementation of the method next(sender:UIButton)

self.viewController?.performSegue (withIdentifier: "toFinish", sender:nil)

The viewController value in this line is nil for the above reason, so the Optional Chaining grammar interrupts this line from running.In other words, there is no screen transition.
Try substituting the property viewController at the appropriate time (for example, immediately after generating the GameScene instance in ViewController.

Another concern is that the property viewController in class GameScene is of type UIViewController?.If this is not a subclass ViewControllerB?, wouldn't the segment toFinish be recognized?


2022-09-30 17:36

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.