天天看點

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)

https://github.com/chukong/cocos-docs/blob/master/tutorial/how-to-make-a-sushicrash-game-by-cocos2dx/part2/zh.md 歡迎大家斧正錯誤,送出pr。

消除壽司的條件檢測

消除壽司

消除壽司時的特效

填補消除壽司後留下的空位

效果圖:

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)

實作之前先來整理整理邏輯!壽司精靈下落後,同行或同列如果有三個或三個以上相同的壽司精靈,那麼應該首先判斷并将其消除。而按照常理,在壽司下落過程中是不能進行消除操作的,是以我們要先定義一個變量,判斷是否有精靈處于下落狀态(即runaction是否完成)。如全部都落到了指定位置,則開始檢測是否有滿足消除條件的壽司,如有,則将其消除并“播放”爆炸特效,同時建立壽司精靈填補空位。遊戲流程如下:

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)

整理好邏輯後,現在就開始我們的工作吧。

對于一個遊戲而言,隻存在場景、層、精靈等實際的元素往往是不夠的,我們需要對這些元素進行必要的邏輯檢測和處理,例如精靈的移動、碰撞、動作等等。而且這些邏輯檢測一般情況下是需要及時做出回報的,是以我們需要在某個方法中不停地循環執行這些邏輯。

cocos2dx遊戲中,遊戲的每一幀都會調用scheduler的update來排程定時器;然後周遊渲染樹,對遊戲畫面進行繪制。是以我們可以重寫update方法實作自己遊戲的邏輯檢測和處理,下面就是update的代碼部分:

m_isanimationing 變量好比一把程式鎖,當精靈們都乖乖的不動時,程式就會開啟它,讓你可以安心地執行消除檢測工作;當有精靈調皮的時候,程式便會鎖上它,避免你在這過程中對精靈”胡作非為”。 

getnumberofrunningactions()方法可以擷取sushi正在執行中的動作個數,如果值大于0,那證明此刻的sushi正處于“調皮”狀态。

update完成了遊戲中最重要的邏輯部分,即下圖粉色部分的内容,checkandremovechain方法中實作藍色部分的内容:

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)

如果要調用update,必須在程式中調用scheduleupdate()定時器。

首先,什麼是定時器呢?從字面上我們可以把它了解為能在特定的時間段裡控制處理某項任務的裝置。然而事實上,在cocos2dx中它的功能也的确如此。當你想讓某個函數不斷的執行,或每隔幾秒執行一次,或隻執行一次時,那麼這些都可以統統交給定時器來完成。

cocos2dx中有三種定時器:schedule,scheduleupdate,scheduleonce。了解了其功能你便會發現定時器真是很簡單,很友善,下面是它們的異同:

scheduleupdate(); 此函數是node的成員函數,每個node隻要調用scheduleupdate(),那麼這個node就會自動重新整理目前類的update(float dt)函數體。scheduleupdate()預設每一幀都會調用update函數。

schedule的作用與scheduleupdate()函數相似,但是scheduleupdate()預設每一幀都會調用update函數,而schedule則可以自定義重新整理的函數體和時間間隔。

[1]schedule(selector); 參數:目标函數,即自定義的更新函數。該函數等同于scheduleupdate,預設每一幀都調用目标函數。

[2]schedule(selector, interval); 參數:目标函數,更新時間。

[3]schedule(selector, interval, repeat, delay); 參數:目标函數,更新時間,更新次數,每次等待時間。

scheduleonce(selector, delay); 參數:目标函數,等待時間。隻執行一次,可以指定重新整理的函數體。

停用定時器的方法:

停止預設的update更新函數。 

unscheduleupdate();

停止自定義更新函數。 

unschedule(selector); 參數:自定義的更新函數。

停止所有更新函數。 

unscheduleallselectors()

檢測是否有符合消除條件的精靈對象是三消類遊戲必不可少的過程,也是最重要的邏輯算法部分之一。

在遊戲中,我們檢測壽司能不能被消除可以這樣做——從壽司矩陣中選取一個壽司,分别查找它的上下、左右是否有與它相鄰并且圖示相同的壽司存在,如存在,則把它們插入到某個清單中,等待進一步的消除操作。

以橫軸上的壽司為例,其原理可用下圖所示圖形來作描述:

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)

在水準方向上以sushi所在的列數為界點,分别向前向後依次檢查是否有精靈的圖示與sushi的圖示相同,如果有相同的,這把它插入chainlist清單中。

其算法如下:

在getcolchain(sushi, chainlist)方法中,sushi是傳入的待檢測壽司精靈,chainlist是存放與sushi相鄰并擁有相同圖示值(imgindex,它決定精靈的種類)的壽司的壽司清單。

縱軸上檢測原理相似,這裡就不做過多描述。

消除壽司之前,需要先判斷并取得可被消除壽司的壽司清單,然後依次取出壽司清單的值把它置為空。

消除算法如下:

在消除類遊戲中,消除精靈的同時一般都會伴有炫麗的爆炸特效,這樣才能吸引玩家的眼球,是以我們也仿照candycrush的消除特效制作了一個簡單的特效。特效由三部分組成:逐漸變小并消失的壽司,逐漸增大并消失的光圈,随機的粒子效果。 

第一二部分特效都可以通過讓壽司精靈執行action來實作,具體方法如下:

這裡callfunc方法是一個動作回調,它派生自actioninstant類,其實就屬于瞬時動作的一種,作用是回調某個類中的方法。cocos2d-x内部使用大量的回調函數來進行消息傳遞(或者說事件調用)。例如:menu的事件觸發,定時器的觸發,action結束時的回調等等。callfunc就是屬于action結束時的回調。

當一個node執行完某個action後,我們可能需要做一些其他的工作(比如從場景移除這個node),這時就可以使用動作回調函數來完成這項功能。在sushicrush特效中,當sprite執行完scaleto動作後,需要将該sprite從父節點中移除,是以這裡我們需要用到動作回調。

cc_callback_0是一個宏定義,其定義使用來c++11的特性,定義如下: 

#define cc_callback_0(__selector__,__target__, …) std::bind(&__selector__,__target__, ##__va_args__)

cocos2d-x引擎提供了強大的粒子系統,它在模仿自然現象、實體現象及空間扭曲上具備得天獨厚的優勢,為我們實作一些真實自然而又帶有随機性的特效(如爆炸、煙花、水流)提供了友善。是以sushicrush爆炸特效的第三部分我們可以利用粒子系統來實作,代碼如下:

particlesystemquad是用于建立粒子系統的類,我們可以通過調用它的create方法來建立一個粒子系統。

cocos2d-x中粒子系統是一個很強大的功能,但因為它有非常多的屬性需要設定和調節,是以使用起來還是有些複雜。

不過你也不用擔心,俗話說兵來将擋,水來土掩,程式員也不是省油的燈。為了能偷懶,我們偉大的程式員開發了粒子編輯器,它可以很友善的編輯出漂亮的粒子效果,讓你勉去手動設定粒子屬性的過程。程式中stars.plist檔案就是由粒子編輯器編輯生成的。

教程中我們所用的粒子編輯器是particledesigner,如下圖所示:

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)
提示:particledesigner不支援windows系統,是以如果你是windows系統,最好還是選擇使用particleeditor吧。

消除壽司後,會留下很多空位,是以接下來我們要把空缺的位置給填補上。 

填補空缺的壽司矩陣位置可以分為兩個過程:1、讓空缺處上面的壽司精靈依次“落”到空缺處 2、建立新的壽司精靈并讓它“落”到矩陣最上方空缺的位置。

原理如下所示:

使用Cocos2d-x制作三消類遊戲Sushi Crush(第二部分)

下面是代碼部分:

結合代碼中的注釋和原理圖,它的實作原理是不是一目了然,很簡單的吧。

好了,今天就到此為止,敬請期待下一章的教程吧。

在下一章中,我們将實作觸摸控制,四消産生特殊壽司,以及特殊壽司爆炸消除一行或列。

繼續閱讀