用Swift做个游戏Lecture09 —— 服务员,说好的菜单呢?
Lecture08课程结束,我们已经走过了90%,剩下的10%是对游戏体验的改进罢了。就比如,刚启动游戏,“Player”就出现在屏幕中Flap一下翅膀,然后还没等用户清楚这个游戏是什么情况的时候,“Player”已经坠地阵亡了。这种游戏体验可谓是差到极致,试想一个用户下载游戏并启动,此时还对游戏没有一丝认知,渴求先看看帮助说明或者玩法介绍之类吧! 因为本课程中,将剔除早前的直接进入游戏的弊端,通过添加主菜单供用户选择开始一次游戏亦或是查看游戏帮助说明等选项。如下: 前文已经给出了游戏状态有如下几种: enum GameState{
case MainMenu
case Tutorial
case Play
case Falling
case ShowingScore
case GameOver
}
当我们开始一个游戏的时候,必须制定当前新游戏的状态,比如是MainMenu显示主菜单呢还是直接进入正题Play开始进行游戏。为此我们自定义一个构造函数 init(size: CGSize,gameState: GameState) {
self.gameState = gameState
super.init(size: size)
}
添加完毕之后,你会发现编译器报错,这也是情理之中,毕竟修改了构造方法导致早前的初始化方法都不能使用了。不急,慢慢修改。请定位到 func switchToNewGame(gameState: GameState) { //改动1 添加了一个传入参数
runAction(popAction)
let newScene = GameScene(size: size,gameState:gameState)//修改传入参数
let transition = SKTransition.fadeWithColor(SKColor.blackColor(),duration: 0.5)
view?.presentScene(newScene,transition: transition)
}
wo ca!!这下早前所有调用 override func touchesBegan(touches: Set<UITouch>,withEvent event: UIEvent?) {
//1
let touch = touches.first
let touchLocation = touch?.locationInNode(self)
switch gameState {
case .MainMenu:
//2
if touchLocation?.y < size.height * 0.15 {
//TODO: 之后添加
} else if touchLocation?.x < size.width * 0.6 {
//3
switchToNewGame(.Tutorial)
}
break
case .Tutorial:
//TODO: 之后添加
break
case .Play:
flapPlayer()
break
case .Falling:
break
case .ShowingScore:
break
case .GameOver:
//4
if touchLocation?.x < size.width * 0.6 {
switchToNewGame(.MainMenu)
}
break
}
}
改动还是蛮大的,起码现在需要根据你点击的位置来执行相应的点击事件:
此时还有个报错来自于”GameViewController.switf文件”,请找到 点击运行,我去!! 咋不灵了….. 貌似 override func didMoveToView(view: SKView) {
physicsWorld.gravity = CGVector(dx: 0,dy: 0)
physicsWorld.contactDelegate = self
addChild(worldNode)
// 以下为替换内容
if gameState == .MainMenu {
switchToMainMenu()
} else {
switchToTutorial()
}
}
//MARK: Game States
//添加剩余两个场景切换方法
func switchToMainMenu() {
gameState = .MainMenu
setupBackground()
setupForeground()
setupPlayer()
setupSomebrero()
//TODO: 实现setupMainMenu()主界面布局 之后把注释去掉
}
func switchToTutorial() {
gameState = .Tutorial
setupBackground()
setupForeground()
setupPlayer()
setupSomebrero()
setupLabel()
//TODO: 实现setupTutorial()教程界面布局 之后把注释去掉
}
其中我们还未实现对主界面的布局,以及教程界面的布局,这也是接下来所要干的事了。 实现主界面的布局: 代码貌似很长,但内容很熟悉不是吗,当年你在配置ScoreCard界面的时候不也这么做过?先布局几个button,然后执行几个动画罢了,请边码边回忆是怎么对精灵位置放置,添加动作的。 func setupMainMenu() {
let logo = SKSpriteNode(imageNamed: "Logo")
logo.position = CGPoint(x: size.width/2,y: size.height * 0.8)
logo.zPosition = Layer.UI.rawValue
worldNode.addChild(logo)
// Play button
let playButton = SKSpriteNode(imageNamed: "Button")
playButton.position = CGPoint(x: size.width * 0.25,y: size.height * 0.25)
playButton.zPosition = Layer.UI.rawValue
worldNode.addChild(playButton)
let play = SKSpriteNode(imageNamed: "Play")
play.position = CGPoint.zero
playButton.addChild(play)
// Rate button
let rateButton = SKSpriteNode(imageNamed: "Button")
rateButton.position = CGPoint(x: size.width * 0.75,y: size.height * 0.25)
rateButton.zPosition = Layer.UI.rawValue
worldNode.addChild(rateButton)
let rate = SKSpriteNode(imageNamed: "Rate")
rate.position = CGPoint.zero
rateButton.addChild(rate)
// Learn button
let learn = SKSpriteNode(imageNamed: "button_learn")
learn.position = CGPoint(x: size.width * 0.5,y: learn.size.height/2 + kMargin)
learn.zPosition = Layer.UI.rawValue
worldNode.addChild(learn)
// Bounce button
let scaleUp = SKAction.scaleTo(1.02,duration: 0.75)
scaleUp.timingMode = .EaseInEaSEOut
let scaleDown = SKAction.scaleTo(0.98,duration: 0.75)
scaleDown.timingMode = .EaseInEaSEOut
learn.runAction(SKAction.repeatActionForever(SKAction.sequence([
scaleUp,scaleDown
])))
}
实现教程界面设置: 反观这个教程界面就显得简单多了,只需要添加一章玩法帮助的图就ok了,如下: func setupTutorial() {
let tutorial = SKSpriteNode(imageNamed: "Tutorial")
tutorial.position = CGPoint(x: size.width * 0.5,y: playableHeight * 0.4 + playableStart)
tutorial.name = "Tutorial"
tutorial.zPosition = Layer.UI.rawValue
worldNode.addChild(tutorial)
let ready = SKSpriteNode(imageNamed: "Ready")
ready.position = CGPoint(x: size.width * 0.5,y: playableHeight * 0.7 + playableStart)
ready.name = "Tutorial"
ready.zPosition = Layer.UI.rawValue
worldNode.addChild(ready)
}
好了,定位到 点击运行项目,恩…出来了,而且再次点击Play会转到教程界面。不过再点击的话,貌似没反应了,聪明的你肯定会转到 为此在下方添加一个 func switchToPlay() {
// 从.Tutorial 状态转到.Play状态
gameState = .Play
// 移除Tutorial精灵
worldNode.enumerateChildNodesWithName("Tutorial",usingBlock: { node,stop in
node.runAction(SKAction.sequence([
SKAction.fadeOutWithDuration(0.5),SKAction.removeFromParent()
]))
})
// 开始产生障碍物 从右向左移动
startSpawning()
// 让Player 向上蹦跶一次...
flapPlayer()
}
点击运行项目,请尽情享受成功的果实吧! 倘若你对游戏某一部分不太熟悉,请到github下载所有课程的代码和课件。
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |