https://github.com/cocos2d/cocos-docs/blob/master/tutorial/how-to-make-a-sushicrash-game-by-cocos2dx/part1/zh.md 歡迎大家斧正錯誤,送出pr。
一直以來,消除類遊戲以其簡單明快的節奏、濃厚的趣味性和智慧性而被廣大玩家所喜愛。其分支三消類遊戲更是倍受廣大遊戲玩家的推崇,最近的candycrush、開心消消樂、天天愛消除等三消遊戲火的那是一個一塌糊塗啊。下面,我們就将和大家一起探讨一下如何制作一款屬于自己的仿candycrush三消遊戲——“sushicrush”。
引擎版本:本教程使用目前最新版本的 cocos2d-x-3.0rc0 引擎。
效果圖:

遊戲架構:為了使項目的代碼結構清晰,好的前期規劃是很有必要的,下圖是該節遊戲工程的主要類結構,先從整體看一下,項目的組織結構,然後我們會對其内部實作做些解說。
其中:
appdelegate.cpp:程式入口,分辨率适配設定。
playlayer.cpp:遊戲場景層,遊戲中所有的node節點都在其内,它同時負責管理sushisprite。
sushisprite.cpp:壽司精靈層,即遊戲中可被消除和操作的對象。
在本章節教程中,我們将主要完成以下功能:
分辨率适配
壽司的建立、布局和下落
appdelegate.cpp是cocos2d-x自動生成的一個類,它控制着遊戲的生命周期,是cocos2d-x遊戲的通用入口檔案,類似于一般 windows 工程中主函數所在的檔案。打開appdelegate.cpp檔案,在applicationdidfinishlaunching()函數中我們可以設定第一個啟動的遊戲場景:
為了能更好的适應各種分辨率大小和螢幕寬高比的移動終端裝置,遊戲的開始,我們還是先來看看分辨率的适配設定。
打開appdelegate.cpp檔案,在applicationdidfinishlaunching函數裡面添加如下代碼,以便我們的遊戲,能夠更好的适應不同的運作環境。
設計分辨率是通過setdesignresolutionsize(width, height, resolutionpolicy)方法來設定的,第一,二個參數分别是設計分辨率的寬度和高度,第三個參數是你想要的模式。這裡設定的分辨率大小是開發時為基準的螢幕分辨率大小。
模式有五種:
exact_fit 整個遊戲内容都會在螢幕内可見,并且不用提供比例系數。x,y會被拉伸,使内容鋪滿螢幕,是以可能會出現形變,所有的應用程式看起來可能會是拉伸或者壓縮的。
no_border 一個方向鋪滿螢幕,另外一個方向超出螢幕,不會變形,但是可能有一些裁剪。
show_all 該模式會盡可能按原始寬高比放大遊戲世界,同時使得遊戲内容全部可見。内容不會形變,不過可能會出現兩條黑邊,即螢幕中會有留白。
fixed_width 該模式會橫向放大遊戲世界内的内容以适應螢幕的寬度,縱向按原始寬高比放大。
fixed_height 與上一中模式相反。
setsearchpaths()方法設定資源搜尋路徑,這裡w640是搜尋的檔案夾名。
setcontentscalefactor()方法設定内容縮放因子,顧名思義,就是設定整個遊戲内容放大或者縮小的比例系數。
sushisprite類繼承于sprite,用來建立單個的壽司精靈,下面是它的類定義:
cc_synthesize的定義如下:
cc_synthesize的作用是定義一個保護型的變量,并聲明一個getfunname函數和setfunname函數,你可以用getfunname函數得到變量的值,用setfunname函數設定變量得值。
參數vartype是變量的類型,m_row是變量名,funname是要聲明函數的“後半截”名字,如:cc_synthesize(int, m_row, row)的作用是聲明一個int型的m_row變量和一個函數名為getrow以及setrow的函數。
壽司精靈的建立:
arc4random()方法擷取随機數比較精确,并且不需要生成随即種子,arc4random() % total_sushi是獲得 0 ~ total_sushi - 1之間的整數。
playlayer是遊戲的主場景,同時也負責管理sushisprite,在該章教程中,playlayer裡我們隻實作了壽司的布局和它的下落。下面我們會詳細講解,先看看playlayer的初始化:
上面的初始化函數中有以下幾點需要說明一下:
plist 和 pvr.ccz檔案
spriteframecache和spritebatchnode
壽司矩陣起始點的初始化
壽司精靈如何布局
遊戲中一般會有比較多的圖檔資源,如果有很多很多的資源,那加載這些資源是非常費時間和記憶體的,是以如何高效地使用圖檔資源對于一款遊戲是相當重要的。在cocos2d中,我們一般會将圖檔資源打包成一張大圖,這樣加載圖檔不僅節省了空間,而且還提升了速度。
打開texturepacker,界面如下圖所示。
texturepacker工具的每個設定項都給出了相應的提示資訊,這裡就不一一介紹。接下來,你就可以根據提示把本章節所需要的6張壽司圖檔資源打包了。導出的時候勾選 output-》texture format-》zlib compr.pvr,然後單擊publish按鈕進行導出,這樣就會導出我們需要的plist 和 pvr.ccz檔案了。
plist檔案是圖檔資訊的屬性清單檔案。
pvr圖像是專門為ios裝置上面的powervr圖形晶片指定的圖像容器。它們在ios裝置上非常好用,因為可以直接加載到顯示卡上面,而不需要經過中間的轉化。pvr.ccz檔案則是pvr檔案格式的壓縮格式,使用這種圖檔格式的好處有兩點:1、可以使你的應用程式更小,因為圖檔是被壓縮過了的。2、你的遊戲能夠啟動地更快。
上面,我們用texturepacker工具打包生成了plist和pvr.ccz檔案,那麼下一步,我們就該擷取plist中的資訊了。
cocos2d中spriteframecache通常用來處理plist檔案,并能與spritebatchnode結合使用來達到批處理渲染精靈的目的。
精靈幀緩存類spriteframecache
精靈幀緩存類spriteframecache 用來存儲精靈幀,緩存精靈幀有助于提高程式的效率。 spriteframecache是一個單例模式,不屬于某個精靈,是所有精靈共享使用的。
精靈批處理節點spritebatchnode
當你需要渲染顯示兩個或兩個以上相同的精靈時,如果逐個渲染精靈,每一次渲染都會調用 opengl es 的 draw 函數,這樣做自然降低了渲染效率。不過幸好,cocos2d為開發者提供了一個spritebatchnode類,它能一次渲染多個精靈。并可以用來批處理這些精靈,比如我們遊戲中的壽司精靈。用spritebatchnode作為父層來建立子精靈,并且使用它來管理精靈類,這樣可以提高程式的效率。
在init()方法中調用spriteframecache的addspriteframeswithfile方法,傳入plist檔案名稱,它會從plist屬性清單檔案的中繼資料部分擷取各個紋理的紋理名,載入到紋理緩存中。并解析屬性清單檔案,使用spriteframe對象來内部地跟蹤所有精靈的資訊。
在cocos2d中高效使用圖檔總結:
使用texturepacker打包圖檔成pvr.ccz檔案,使用spritebatchnode優化繪制,使用spriteframecache緩存讀取,使用spritewithframename擷取單張圖檔。
在遊戲中,我們用來存儲sushisprite的資料結構是一個指針數組,其實它也就相當于一個矩陣。壽司矩陣的起始點其實就是壽司精靈開始布局的起始點,在我們的遊戲教程中,它位于螢幕的左下角,它由左下角的點開始逐行逐列的初始化壽司精靈。計算該點的公式如下:
其原理可簡單描述為下圖所示的過程(隻以計算m_matrixleftbottomx的值為例,即x軸方向坐标值):
看原理圖其實就已經一目了然了,上圖n代表的是橫向布局的壽司精靈數,m_matrixleftbottomx的值 = ( 螢幕的寬 - 壽司的寬*n個壽司 - ( n-1 )*壽司之間的間隙) / 2。
加載完壽司精靈圖檔,計算好壽司精靈布局的起始點以後,我們就可以開始壽司精靈的布局和它的下落顯示了,下面是代碼行:
我們先來看怎樣擷取指定行列精靈在螢幕上的坐标值,即positionofitem(row, col)方法的實作。同樣附上原理圖,友善了解。
上圖矩陣的起始點已知(m_matrixleftbottomx,m_matrixleftbottomy),計算第row行col列的壽司精靈的坐标值。
需要說明的是,精靈圖檔的錨點預設在圖檔的中心位置,錨點關系到紋理貼圖的位置。例如:如果把一個精靈設定在(0,0)點的位置,那麼它的錨點也就會和(0,0)點重合,在螢幕上也就隻能顯示四分之一的精靈。是以往往為了避免這種問題,在貼精靈圖檔的時候我們會加上它寬高的一半。
言歸正傳,結合上面的原理圖,你将很容易了解(x, y)是如何計算的。
最後,壽司精靈的建立和下落方法:createanddropsushi(row, col)。
壽司精靈的建立一幕了然,它的下落是通過讓壽司精靈執行moveto動作來實作的,具體方法是把壽司精靈的起點設定在比終點(可以通過positionofitem方法擷取)高size.height / 2的地方,再讓其以一定的速度從起點移動到終點。原理如下圖所示:
至此,我們第一章的内容久講完了。
在下一章中,我們将實作初次掉落的消除檢查,并自動消除三個連在一起的壽司,然後掉落新的壽司補齊空缺。