原理介紹
Cocos2d-x調度器為游戲提供定時事件和定時調用服務。所有Node對象都知道如何調度和取消調度事件,使用調度器有幾個好處:
- 每當Node不再可見或已從場景中移除時,調度器會停止。
- Cocos2d-x暫停時,調度器也會停止。當Cocos2d-x重新開始時,調度器也會自動繼續啟動。
- Cocos2d-x封裝了一個供各種不同平台使用的調度器,使用此調度器你不用關心和跟蹤你所設定的定時對象的銷毀和停止,以及崩潰的風險。
基礎用法
游戲中我們經常會隨時間的變化而做一些邏輯判斷,如碰撞檢測。為了解決以上問題,我們引入了調度器,這使得游戲能夠更好的處理動態事件。Cocos2d-x提供了多種調度機制,在開發中我們通常會用到3種調度器:
- 默認調度器:schedulerUpdate()
- 自定義調度器:schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
- 單次調度器:scheduleOnce(SEL_SCHEDULE selector, float delay)
以下我們來對這3種調度器做簡單的介紹。
默認調度器(schedulerUpdate)
該調度器是使用Node的刷新事件update方法,該方法在每幀繪制之前都會被調用一次。由於每幀之間時間間隔較短,所以每幀刷新一次已足夠完成大部分游戲過程中需要的邏輯判斷。
Cocos2d-x中Node默認是沒有啟用update事件的,因此你需要重載update方法來執行自己的邏輯代碼。
通過執行schedulerUpdate()調度器每幀執行 update方法,如果需要停止這個調度器,可以使用unschedulerUpdate()方法。
以下代碼用來測試該調度器:
HelloWorldScene.h void update(float dt)override; HelloWorldScene.cpp boolHelloWorld::init() { scheduleUpdate(); return true; } void HelloWorld::update(float dt) { log("update"); }
你會看到控制台不停輸出如下信息
cocos2d: update cocos2d: update cocos2d: update cocos2d: update
自定義調度器(scheduler)
游戲開發中,在某些情況下我們可能不需要頻繁的進行邏輯檢測,這樣可以提高游戲性能。所以Cocos2d-x還提供了自定義調度器,可以實現以一定的時間間隔連續調用某個函數。
由於引擎的調度機制,自定義時間間隔必須大於兩幀的間隔,否則兩幀內的多次調用會被合並成一次調用。所以自定義時間間隔應在0.1秒以上。
同樣,取消該調度器可以用unschedule(SEL_SCHEDULE selector, float delay)。
以下代碼用來測試該調度器:
HelloWorldScene.h void updateCustom(float dt); HelloWorldScene.cpp bool HelloWorld::init() { schedule(schedule_selector(HelloWorld::updateCustom),1.0f, kRepeatForever,0); return true; } void HelloWorld::updateCustom(float dt) { log("Custom"); }
在控制台你會看到每隔1秒輸出以下信息
cocos2d:Custom cocos2d:Custom cocos2d:Custom cocos2d:Custom cocos2d:Custom
我們來看下scheduler(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)函數里面的參數:
- 第一個參數selector即為你要添加的事件函數
- 第二個參數interval為事件觸發時間間隔
- 第三個參數repeat為觸發一次事件后還會觸發的次數,默認值為kRepeatForever,表示無限觸發次數
- 第四個參數delay表示第一次觸發之前的延時
單次調度器(schedulerOnce)
游戲中某些場合,你只想進行一次邏輯檢測,Cocos2d-x同樣提供了單次調度器。該調度器只會觸發一次,用unschedule(SEL_SCHEDULE selector, float delay)來取消該觸發器。
以下代碼用來測試該調度器:
HelloWorldScene.h
void updateOnce(float dt);
HelloWorldScene.cpp bool HelloWorld::init()
{ scheduleOnce(schedule_selector(HelloWorld::updateOnce),0.1f); return true;
}
voidHelloWorld::updateOnce(float dt) { log("Once"); }
這次在控制台你只會看到一次輸出
cocos2d:Once
