2016-11-17 131 views
1

我已經在Xcode中創建了一個遊戲,但是我想在玩家輸掉的時候切換到屏幕上的遊戲,此時main.storyboard文件是空白的。我發現這個解決方案Using a view controller for a game over scene將遊戲實現爲快速遊戲

但是,我不確定如何實現這個到我的代碼。我附上了我的代碼,如果有人可以幫助我,這將不勝感激。

import SpriteKit 
import GameplayKit 

class GameScene: SKScene, SKPhysicsContactDelegate { 

var bird = SKSpriteNode() 

var bg = SKSpriteNode() 

var scoreLabel = SKLabelNode() 

var score = 0 

var gameOverLabel = SKLabelNode() 

var timer = Timer() 

enum ColliderType: UInt32 { 

    case Bird = 1 
    case Object = 2 
    case Gap = 4 

} 

var gameOver = false 

func makePipes() { 

    let movePipes = SKAction.move(by: CGVector(dx: -2 * self.frame.width, dy: 0), duration: TimeInterval(self.frame.width/100)) 

    let gapHeight = bird.size.height * 4 

    let movementAmount = arc4random() % UInt32(self.frame.height/2) 

    let pipeOffset = CGFloat(movementAmount) - self.frame.height/4 

    let pipeTexture = SKTexture(imageNamed: "pipe1.png") 

    let pipe1 = SKSpriteNode(texture: pipeTexture) 

    pipe1.position = CGPoint(x: self.frame.midX + self.frame.width, y: self.frame.midY + pipeTexture.size().height/2 + gapHeight/2 + pipeOffset) 

    pipe1.run(movePipes) 

    pipe1.physicsBody = SKPhysicsBody(rectangleOf: pipeTexture.size()) 
    pipe1.physicsBody!.isDynamic = false 

    pipe1.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue 
    pipe1.physicsBody!.categoryBitMask = ColliderType.Object.rawValue 
    pipe1.physicsBody!.collisionBitMask = ColliderType.Object.rawValue 

    pipe1.zPosition = -1 

    self.addChild(pipe1) 

    let pipe2Texture = SKTexture(imageNamed: "pipe2.png") 

    let pipe2 = SKSpriteNode(texture: pipe2Texture) 

    pipe2.position = CGPoint(x: self.frame.midX + self.frame.width, y: self.frame.midY - pipe2Texture.size().height/2 - gapHeight/2 + pipeOffset) 

    pipe2.run(movePipes) 

    pipe2.physicsBody = SKPhysicsBody(rectangleOf: pipeTexture.size()) 
    pipe2.physicsBody!.isDynamic = false 

    pipe2.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue 
    pipe2.physicsBody!.categoryBitMask = ColliderType.Object.rawValue 
    pipe2.physicsBody!.collisionBitMask = ColliderType.Object.rawValue 

    pipe2.zPosition = -1 

    self.addChild(pipe2) 

    let gap = SKNode() 

    gap.position = CGPoint(x: self.frame.midX + self.frame.width, y: self.frame.midY + pipeOffset) 

    gap.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: pipeTexture.size().width, height: gapHeight)) 

    gap.physicsBody!.isDynamic = false 

    gap.run(movePipes) 

    gap.physicsBody!.contactTestBitMask = ColliderType.Bird.rawValue 
    gap.physicsBody!.categoryBitMask = ColliderType.Gap.rawValue 
    gap.physicsBody!.collisionBitMask = ColliderType.Gap.rawValue 

    self.addChild(gap) 

} 

func didBegin(_ contact: SKPhysicsContact) { 

    if gameOver == false { 

    if contact.bodyA.categoryBitMask == ColliderType.Gap.rawValue || contact.bodyB.categoryBitMask == ColliderType.Gap.rawValue { 

     score += 1 

     scoreLabel.text = String(score) 

    } else { 

    self.speed = 0 

    gameOver = true 

    timer.invalidate() 

    gameOverLabel.fontName = "Helvetica" 

    gameOverLabel.fontSize = 30 

    gameOverLabel.text = "Game Over! Tap to play again." 

    gameOverLabel.position = CGPoint(x: self.frame.midX, y: self.frame.midY) 

    self.addChild(gameOverLabel) 

     } 
    } 

} 


override func didMove(to view: SKView) { 

    self.physicsWorld.contactDelegate = self 

    setupGame() 


} 

func setupGame() { 

    timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.makePipes), userInfo: nil, repeats: true) 

    let bgTexture = SKTexture(imageNamed: "bg.png") 

    let moveBGAnimation = SKAction.move(by: CGVector(dx: -bgTexture.size().width, dy: 0), duration: 7) 
    let shiftBGAnimation = SKAction.move(by: CGVector(dx: bgTexture.size().width, dy: 0), duration: 0) 
    let moveBGForever = SKAction.repeatForever(SKAction.sequence([moveBGAnimation, shiftBGAnimation])) 

    var i: CGFloat = 0 

    while i < 3 { 

     bg = SKSpriteNode(texture: bgTexture) 

     bg.position = CGPoint(x: bgTexture.size().width * i, y: self.frame.midY) 

     bg.size.height = self.frame.height 

     bg.run(moveBGForever) 

     bg.zPosition = -2 

     self.addChild(bg) 

     i += 1 

    } 


    let birdTexture = SKTexture(imageNamed: "flappy1.png") 
    let birdTexture2 = SKTexture(imageNamed: "flappy2.png") 

    let animation = SKAction.animate(with: [birdTexture, birdTexture2], timePerFrame: 0.1) 
    let makeBirdFlap = SKAction.repeatForever(animation) 

    bird = SKSpriteNode(texture: birdTexture) 

    bird.position = CGPoint(x: self.frame.midX, y: self.frame.midY) 

    bird.run(makeBirdFlap) 

    bird.physicsBody = SKPhysicsBody(circleOfRadius: birdTexture.size().height/2) 

    bird.physicsBody!.isDynamic = false 

    bird.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue 
    bird.physicsBody!.categoryBitMask = ColliderType.Bird.rawValue 
    bird.physicsBody!.collisionBitMask = ColliderType.Bird.rawValue 

    self.addChild(bird) 

    let ground = SKNode() 

    ground.position = CGPoint(x: self.frame.midX, y: -self.frame.height/2) 

    ground.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: self.frame.width, height: 1)) 

    ground.physicsBody!.isDynamic = false 

    ground.physicsBody!.contactTestBitMask = ColliderType.Object.rawValue 
    ground.physicsBody!.categoryBitMask = ColliderType.Object.rawValue 
    ground.physicsBody!.collisionBitMask = ColliderType.Object.rawValue 


    self.addChild(ground) 

    scoreLabel.fontName = "Helvetica" 

    scoreLabel.fontSize = 60 

    scoreLabel.text = "0" 

    scoreLabel.position = CGPoint(x: self.frame.midX, y: self.frame.height/2 - 220) 

    self.addChild(scoreLabel) 





} 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 

    if gameOver == false { 


    bird.physicsBody!.isDynamic = true 

    bird.physicsBody!.velocity = CGVector(dx: 0, dy: 0) 

    bird.physicsBody!.applyImpulse(CGVector(dx: 0, dy: 80)) 

    } else { 

     gameOver = false 

     score = 0 

     self.speed = 1 

     self.removeAllChildren() 

     setupGame() 

    } 

    } 


override func update(_ currentTime: TimeInterval) { 
    // Called before each frame is rendered 
} 



} 

回答

2

您應該設置GameOverScene並在需要時顯示此場景。該RayWenderlich網站已經很多教程將告訴你如何做到這一點,很可能過多解釋這裏

這裏是到

This page鏈接展示瞭如何實現一個級別完整覆蓋)

但基本上你只需要創建一個新的場景,添加任何UI元素它,你需要的,然後從視圖控制器,你可以撥打PresentScene,像這樣

view.presentScene(scene) 

示例代碼:

class GameScene: SKScene { 

    var notificationLabel = SKLabelNode(text: "Tap the screen to win") 
    override func didMove(to view: SKView) { 

     self.backgroundColor = SKColor.black 

     addChild(notificationLabel) 
     notificationLabel.fontSize = 32.0 
     notificationLabel.color = SKColor.white 
     notificationLabel.fontName = "Thonburi-Bold" 
     notificationLabel.position = CGPoint(x: size.width/2, y: size.height/2) 
    } 

    func displayGameOver() { 

     let gameOverScene = GameOverScene(size: size) 
     gameOverScene.scaleMode = scaleMode 

     let reveal = SKTransition.flipHorizontal(withDuration: 0.5) 
     view?.presentScene(gameOverScene, transition: reveal) 
    } 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 

     displayGameOver() 
    } 
} 

class GameOverScene: SKScene { 

    var notificationLabel = SKLabelNode(text: "You Won") 

    override init(size: CGSize) { 
     super.init(size: size) 

     self.backgroundColor = SKColor.darkGray 

     addChild(notificationLabel) 
     notificationLabel.fontSize = 32.0 
     notificationLabel.color = SKColor.white 
     notificationLabel.fontName = "Thonburi-Bold" 
     notificationLabel.position = CGPoint(x: size.width/2, y: size.height/2) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 

     let gameScene = GameScene(size: size) 
     gameScene.scaleMode = scaleMode 

     let reveal = SKTransition.flipHorizontal(withDuration: 0.5) 
     view?.presentScene(gameScene, transition: reveal) 
    } 
} 

在任一場景中點擊屏幕都會顯示其他場景。你也應該可以通過viewcontroller來管理它,並做幾乎相同的事情,但是我還沒有這樣做,我自己對SpriteKit還是比較新的。

希望這有助於

+0

所有上面的代碼是在GameScene.swift,本教程顯示了IBOutlets添加到GameViewController.swift如果我添加一切都在那裏,我怎麼能叫它當遊戲結束運行。目前我只有一個標籤,彈出並停止遊戲運行。對不起,如果我不理解,我是新的發展 – uz7

+0

我會做一個例子,並很快發佈 – Scriptable

+0

謝謝,我期待着看到它。 – uz7