<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)
}
}
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?
© 2024 OneMinuteCode. All rights reserved.