Swift开发Sprite Kit游戏实践(四):背景音乐与Game Over
来源:互联网 发布:微观调查数据 编辑:程序博客网 时间:2024/06/08 09:00
- Game Over!
如果monkey跟敌人相撞,或落出屏幕的话,就会显示”Game Over“,接着出现重新点击开始游戏的画面。
首先将以下所有变量添加到GameScene顶端,在 let player = SKSpriteNode(imageNamed:”spacemonkey_fly02”)之后:
// 1 var gameOver = false // 2 let endLabel = SKLabelNode(text: "Game Over") let endLabel2 = SKLabelNode(text: "Tap to restart!") let touchToBeginLabel = SKLabelNode(text: "Touch to begin!") let points = SKLabelNode(text: "0") // 3 var numPoints = 0 // 4 let explosionSound = SKAction.playSoundFileNamed("explosion.mp3", waitForCompletion: true) let coinSound = SKAction.playSoundFileNamed("coin.wav", waitForCompletion: false)
再回顾一下上述步骤:
- 首先创建一个gameOver布尔变量,不论游戏是否结束,都进行跟踪记录。
- 创建一些label node,好在Sprite Kit中设置屏幕上显示的字幕。
- 创建integer储存分数。注意,用var来标记 integer,不是let,方便之后进行修改。
- 最后创建一些action,随后制造音效。
下一步创建名为setupLabels()的新方法:
func setupLabels() { // 1 touchToBeginLabel.position = CGPoint(x: frame.size.width/2, y: frame.size.height/2) touchToBeginLabel.fontColor = UIColor.whiteColor() touchToBeginLabel.fontSize = 50 addChild(touchToBeginLabel) // 2 points.position = CGPoint(x: frame.size.width/2, y: frame.size.height * 0.1) points.fontColor = UIColor.whiteColor() points.fontSize = 100 addChild(points) }
再回顾一下上述步骤:
- 将“touch to begin(点击开始)”标签放在屏幕中央,字体白色,大小50pt。
- 将position label设在屏幕底端,白色,大小100。
现在在didMoveToView(_:)里调用setupLabels():
setupLabels()
再删掉touchesBegan(_:withEvent:),添加如下代码:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { // 1 if (!gameOver) { if player.physicsBody?.dynamic == false { player.physicsBody?.dynamic = true touchToBeginLabel.hidden = true backgroundColor = SKColor.blackColor() runAction(SKAction.repeatActionForever( SKAction.sequence([ SKAction.runBlock(spawnEnemy), SKAction.waitForDuration(1.0)]))) } // 2 jumpPlayer() } // 3 else if (gameOver) { let newScene = GameScene(size: size) newScene.scaleMode = scaleMode let reveal = SKTransition.flipHorizontalWithDuration(0.5) view?.presentScene(newScene, transition: reveal) } }
回顾一下:
- 如果游戏还没结束,monkey还处于非动态(受物理引擎控制),同样说明新游戏还没开始。这时将dynamic设置为true,隐藏label,大批敌人开始出现在屏幕上。
- 不管怎样都要调用 jumpPlayer ,因为只有dynamic 设置为true的时候,它才能被调用。
- 如果游戏结束了,要重新开始,那么创建一个新的GameScene ,显示在屏幕上。
接下来在代码中添加如下方法:
override func update(currentTime: CFTimeInterval) { //1 if !gameOver { //2 if player.position.y <= 0 { endGame() } //3 enumerateChildNodesWithName("enemy") { enemy, _ in //4 if enemy.position.x <= 0 { //5 self.updateEnemy(enemy) } } } }
回顾一下:
- 如果gameOver 为false的话,看看monkey是否消失了,如果是,调用endGame——这个随后再添加。
- 用enumerateChildNodesWithName 查看场景中的带有“enemy(敌人)“的对象。每当一个敌人消失,就会调用updateEnemy()——这个也是随后再添加。
现在添加名为updateEnemy()的method,在框架渲染前调用——产生的效果是:每当一个敌人消失,玩家就会得1分:
func updateEnemy(enemy: SKNode) { //1 if enemy.position.x < 0 { //2 enemy.removeFromParent() //3 runAction(coinSound) //4 numPoints++ //5 points.text = "\(numPoints)" } }
再回顾一下上述步骤:
- 看一下敌人是否在在屏幕外的x轴上。
- 如果是,把敌人从parent上移除(从游戏中移除)。
- 将玩家分数储存在numPoints里。
- 将分数转化为分数条,再将分数条插入分数label。
现在需要稍稍改变下didBeginContact(_:)了。从parent移除第一个节点之后,添加这行代码:
endGame()
现在终于可以用endGamemethod了,久等了:
func endGame() { // 1 gameOver = true // 2 removeAllActions() // 3 runAction(explosionSound) // 4 endLabel.position = CGPoint(x: frame.size.width/2, y: frame.size.height/2) endLabel.fontColor = UIColor.whiteColor() endLabel.fontSize = 50 endLabel2.position = CGPoint(x: frame.size.width/2, y: frame.size.height/2 + endLabel.fontSize) endLabel2.fontColor = UIColor.whiteColor() endLabel2.fontSize = 20 points.fontColor = UIColor.whiteColor() addChild(endLabel) addChild(endLabel2) }
现在来回顾一下:
- 将gameOver设置为true。
- 移除场景中的所有action,终止所有动画效果。
- 运行爆炸声效。
- 定位,再为场景添加endLabel。
现在用didMoveToView(_:)移除这个代码块:
ackgroundColor = SKColor.blackColor() runAction(SKAction.repeatActionForever( SKAction.sequence([ SKAction.runBlock(spawnEnemy), SKAction.waitForDuration(1.0)])))
最后添加一行:
player.physicsBody?.dynamic = false
这样设置之后,点击屏幕后游戏才会开始,否则monkey是不会移动的。
编写完成后运行,游戏大功告成了!
- 背景音乐
等会儿,还有一件事!打开ViewController.swift,添加一个新属性:
var backgroundMusicPlayer: AVAudioPlayer!
还要添加一个新method:
func playBackgroundMusic(filename: String) { let url = NSBundle.mainBundle().URLForResource( filename, withExtension: nil) if (url == nil) { println("Could not find file: \(filename)") return } var error: NSError? = nil backgroundMusicPlayer = AVAudioPlayer(contentsOfURL: url, error: &error) if backgroundMusicPlayer == nil { println("Could not create audio player: \(error!)") return } backgroundMusicPlayer.numberOfLoops = -1 backgroundMusicPlayer.prepareToPlay() backgroundMusicPlayer.play() }
这个method很方便,用来添加一些背景音乐。工作原理在此不详述。
用起来很简单,只要在skView.presentScene(scene)那一行后添加viewWillLayoutSubviews():
playBackgroundMusic("BackgroundMusic.mp3")
编写好之后运行,美妙的背景音乐出现啦!太棒了!
转自:http://www.csdn.net/article/2015-05-26/2824772-sprite-kit-for-kids-with-swift/4
- Swift开发Sprite Kit游戏实践(四):背景音乐与Game Over
- Swift开发Sprite Kit游戏实践(一)
- Swift开发Sprite Kit游戏实践(三):物理推力与碰撞检测
- Swift开发Sprite Kit游戏实践(二):让敌人们动起来
- Sprite Kit Swift游戏开发新手指导手册(1)
- Sprite Kit Swift游戏开发新手指导手册(2)
- Sprite Kit Swift游戏开发新手指导手册(3)
- Sprite Kit Swift游戏开发新手指导手册(4)
- Sprite Kit Swift游戏开发新手指导手册(5)
- Sprite Kit编程指南(9)-Sprite Kit最佳实践
- Sprite Kit编程指南(9)-Sprite Kit最佳实践
- Sprite Kit编程指南(9)-Sprite Kit最佳实践
- Sprite Kit编程指南(9)-Sprite Kit最佳实践
- Sprite Kit编程指南(9)-Sprite Kit最佳实践
- ios游戏开发 Sprite Kit教程(一)
- ios游戏开发 Sprite Kit教程(二)
- Card Game Mechanics in Sprite Kit with Swift
- 游戏中的三角学——Sprite Kit 和 Swift 教程(1)
- 欢迎使用CSDN-markdown编辑器
- Eclipse 和 MyEclipse控制台console不停的自动跳动,跳出来解决方案http://jmhmlu.blog.163.com/blog/static/16161229820124311
- DebugGap 3.0.0 开始支持Windows Phone下的IE
- 多线程之四:MFC多线程通讯
- TabHost使用注意
- Swift开发Sprite Kit游戏实践(四):背景音乐与Game Over
- UIButton中setTitleEdgeInsets和setImageEdgeInsets的使用
- windows等待函数
- QQ通信原理及QQ是怎么穿透内网进行通信的?
- 【JAVA】什么叫回调方法
- Objective-C开发编码规范:4大方面解决开发中的规范性问题
- 专访支付宝首席架构师程立
- 【回调函数】透彻理解
- 遍历数组的同时删除