火男無腦開發錄
前介
- 開發引擎:SpriteKit
- 開發語言:Swift
- 其他:NodeJS(放棄) ,MySQL(放棄)
走著
我寫了個標題叫極致,我要做個游戲,然后順帶寫這個教程,但是實際上意思是反的,我以做個游戲的名義來特地寫個教程。
先介紹將要開發的游戲,一款類似跑酷類型,主角為一只小兔子,游戲開始會一直往前沖,但是前面卻是萬丈深淵,所以需要玩家點擊屏幕在下方生成一個平臺,避免小兔子掉下去,玩家需要控制平臺升降的高度,太高了小兔子會上不去gg,如果平臺降得很低,小兔子也將掉出屏幕,同樣gg。游戲的目標是,在有限的下降空間內讓小兔子跑得更遠,后面編寫的后臺程序將紀錄下每次小兔子的跑酷紀錄,然后寫入數據庫,當點開排名界面的時候,將從后臺獲取前10位玩家的紀錄。
流程就介紹完了,開干吧……
因為打算只針對游戲開發流程,所以其他不相干的知識盡量摒棄,前提是熟悉Swift 這門語言,而SpriteKit 也僅支持Obj-C 和Swift 。
以下為將用到的美術資源
新建工程
直接選擇Game ,填寫項目名語言、框架、運行的平臺。
next保存到目錄,xcode與git是無縫銜接的,需要版本管理或遠程協同就選上吧。
一個簡單的工程,默認有架飛機,但是刪掉,
GameScene
中涉及不相干邏輯的部分也刪掉,并且不涉及游戲邏輯的類文件或資源文件放在新建的Group 中。
創建第一個類
configue
用來保存游戲中的全局屬性。
游戲畫面尺寸設置為1242*2208,因為我們的游戲場景是用的sks文件讀取的方式,所以sks文件中需要手動設置一下場景尺寸跟winSize
一致即可。
設計好游戲邏輯的層級關系
- 菜單層
- 角色層
- 背景層
屏幕快照 2016-06-04 下午8.55.59.png
游戲中各類元素的前后關系寫在configure
中,姑且把configure
看作是包含各種宏定義的類吧。
屏幕快照 2016-06-04 下午9.01.08.png
notificationCenter
為獲取的消息中心實例,backgroundMove``backgroundStop
用來表示控制背景移動和停止的消息名稱。
編寫內容
先從地面平臺開始,一步步拓展看,地面以一條三塊土方組合成的平臺柱子為一個單位,分為上中下,中層可以根據需要放置一個或者多個土塊,上下土塊固定好。
創建土塊
打開GroundCobe.swift
編寫以下代碼
以最上層的土塊貼圖創建
SKSpriteNode
對象,在此基礎上添加中層土塊,最后在底部添加下層土塊。完成這一步,開始創建整個游戲的背景類,稍后將在背景類中添加土塊。
創建背景
打開Background.swift
編寫以下代碼
notificationCenter.addObserver(self, selector: #selector(Background.move), name: kBackgroundMove, object: nil)
notificationCenter.addObserver(self, selector: #selector(Background.stop), name: kBackgroundStop, object: nil)
添加兩個消息監聽用來控制背景的移動和停止,當小兔子掉落的時候,背景保持禁止,當小兔子跑動的時候,背景往后移動。
在GameScene.swift
中的didFinishUpdate
中添加背景的更新函數調用
override func didFinishUpdate() {
background.didFinishUpdate()
}
創建小兔子
小兔子的素材分三組動畫序列幀,跑動,禁止,下落
打開Player.swift
編寫以下代碼
state
用來表示小兔子當前的狀態,并定義分別包含三種狀態序列幀的貼圖數組runTextures
fallTextures
stayTextures
。
添加以下方法,用來切換小兔子狀態,并通知背景層做相應停止或移動處理,這樣只需要控制小兔子的狀態,便能讓背景的狀態與只同步。
//Mark:角色動作狀態切換
func setState(newState: PlayerState){
state = newState
removeAllActions()
switch state! {
case .Run:
let action = SKAction.animateWithTextures(runTextures, timePerFrame: 0.1)
runAction(SKAction.repeatActionForever(action))
//通知背景開始平移
????notificationCenter.postNotificationName(kBackgroundMove, object: nil)
case .Fall:
??let action = SKAct????ion.animateWithTextures(fallTextures, timePerFrame: 0.2)
runAction(action)
//通知背景停止平移
notificationCenter.postNotificationName(kBackgroundStop, object: nil)
case .Stay:
let action = SKAction.animateWithTextures(stayTextures, timePerFrame: 0.1)
runAction(SKAction.repeatActionForever(action))
//通知背景停止平移
notificationCenter.postNotificationName(kBackgroundStop, object: nil)
}
需要模擬兔子的墜落效果,那么給兔子添加物理體
private func setPhysics(){
physicsBody = SKPhysicsBody(circleOfRadius: size.width * 0.4)
physicsBody?.allowsRotation = false
physicsBody?.categoryBitMask = Bitmask.player
physicsBody?.collisionBitMask = Bitmask.cobe //設置能與之產生物理碰撞的物體
physicsBody?.contactTestBitMask = Bitmask.cobe | Bitmask.enemy //設置能與之檢測碰撞的物體
physicsBody?.restitution = 0 //設置反彈力度
}
configure.swift
中定義的各個物體物理體是UInt32
類型,意味著一個游戲可以創建32種不同類型的物理體,應該足夠了
//物理體
struct Bitmask{
static let cobe:UInt32 = 0x1 << 1 //地面
static let player:UInt32 = 0x1 << 2 //角色
static let enemy:UInt32 = 0x1 << 3 //障礙物
}
在GameScene中合并它們
準確的說法是編寫控制土塊移動的交互代碼和小兔子狀態被動切換的代碼
物理體協議
這個。。。有個小意外,本來是通過物理體碰撞來控制小兔子的狀態切換,后來發現這種方式很不靠譜,所以不用了。而且后來我做的項目基本上是避免讓他附帶物理效果,或者能自己寫編自己寫,實際上原生得并不好控制細節(除非只需要真實的物理模擬)
讓兔子活動起來
在GameScene.swift
下的Update
函數中寫一些簡單代碼
override func update(currentTime: CFTimeInterval) {
//當小兔子位置超出屏幕便結束游戲
if player.position.y < 0 || player.position.x > winSize.width || player.position.x < 0 {
isGameover = true
}
//既然結束游戲了,下面就不執行了guard的具體含義百度百度
guard !isGameover else{
return
}
//通過獲取小兔子當前的運動矢量來判斷小兔子當前的狀態
//dy<0 意味著它正在下落,那么切換兔子狀態吧
//否則dx<0意味著它被卡住了,游戲結束,并切換狀態為停止
//否則意味著它在平地上了,那么讓它跑起來吧
let playerVelocity = player.physicsBody!.velocity
if playerVelocity.dy < 0 {
player.setState(.Fall)
}else{
if playerVelocity.dx < -0.05 {
isGameover = true
player.setState(.Stay)
}else{
player.setState(.Run)
}
}
}
完事
大概就是這么個過程,原來還有不少東西要寫,我簡化了些,但是。。。這玩意能跑
呵呵
美術圖地址:百度網盤