注:本文開始,引擎升級到cocos2dx 3.6
在遊戲開發過程中,經常會遇到使用計時器的情況,例如:倒計時,定時炸彈等。scheduler是cocos2dx 2.x時代就已經存在的產物,主要用於各種延時函數以及各種每幀運行的函數。本文主要介紹scheduler的API函數以及使用方法。
首先,所有繼承Node的類都可以使用scheduler,以下是Node類下相關API的介紹
/**
* 開啓自帶的update方法,這個方法會每幀執行一次,默認優先級爲0,並且在所有自定義方法執行之前執行
*/
void scheduleUpdate(void);
/**
* 開啓自帶的update方法,這個方法會每幀執行一次,設定的優先級越小,越優先執行
*/
void scheduleUpdateWithPriority(int priority);
/**
* 關閉自帶的update方法
*/
void unscheduleUpdate(void);
/**
* 定義一個自定義的定時器
* selector:回調函數
* interval:重複間隔時間,重複執行間隔的時間,如果傳入0,則表示每幀調用
* repeat:重複運行次數,如果傳入CC_REPEAT_FOREVER則表示無限循環
* delay:延時秒數,延遲delay秒開始執行第一次回調
*/
void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
/**
* 定義一個立即執行的無限循環的自定義定時器
* interval:重複間隔時間,重複執行間隔的時間,如果傳入0,則表示每幀調用
*/
void schedule(SEL_SCHEDULE selector, float interval);
/**
* 定義一個延遲執行的單次自定義定時器
* delay:延時秒數,延遲delay秒開始執行第一次回調
*/
void scheduleOnce(SEL_SCHEDULE selector, float delay);
/**
* 定義了一個無限循環、立即執行並且每幀都會執行的自定義定時器(和scheduleUpdate效果一樣,但是會在scheduleUpdate之後執行)
*/
void schedule(SEL_SCHEDULE selector);
/**
* 使用lambda函數定義一個每幀調用的自定義定時器
* callback:lambda函數
* key:lambda函數的Key,用於取消定時器
*/
void schedule(const std::function<void(float)>& callback, const std::string &key);
/**
* 使用lambda函數定義一個每隔interval秒調用的自定義定時器
* callback:lambda函數
* interval:重複間隔時間,重複執行間隔的時間,如果傳入0,則表示每幀調用
* key:lambda函數的Key,用於取消定時器
*/
void schedule(const std::function<void(float)>& callback, float interval, const std::string &key);
/**
* 使用lambda函數定義一個自定義定時器
* callback:lambda函數
* interval:重複間隔時間,重複執行間隔的時間,如果傳入0,則表示每幀調用
* repeat:重複運行次數,如果傳入CC_REPEAT_FOREVER則表示無限循環
* delay:延時秒數,延遲delay秒開始執行第一次回調
* key:lambda函數的Key,用於取消定時器
* @lua NA
*/
void schedule(const std::function<void(float)>& callback, float interval, unsigned int repeat, float delay, const std::string &key);
/**
* 取消一個自定義定時器
*/
void unschedule(SEL_SCHEDULE selector);
/**
* 取消本節點上所有的定時器(包括scheduleUpdate開啓的定時器)
*/
void unscheduleAllSelectors(void);
接下來用一個簡單的倒計時例子來學習API的使用,首先看看實現效果:
具體代碼如下:
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
//int _time;
//Label *_countdownLabel; //類成員變量
_time = 10;
_countdownLabel = Label::create(String::createWithFormat("%d", _time)->getCString(), "微軟雅黑", 24);
_countdownLabel->setPosition(Vec2(200, 200));
addChild(_countdownLabel);
//方法1
//schedule(schedule_selector(HelloWorld::NextTime),1.f,CC_REPEAT_FOREVER,0.0f);
//方法2
schedule([&](float dt)
{
if (_time == 0)
{
unschedule("CountDown");
_countdownLabel->setString("end");
}
else
{
--_time;
_countdownLabel->setString(String::createWithFormat("%d", _time)->getCString());
}
}, 1.f, CC_REPEAT_FOREVER, 0.0f, "CountDown");
return true;
}
void HelloWorld::NextTime(float dt)
{
if (_time == 0)
{
unschedule(schedule_selector(HelloWorld::NextTime));
_countdownLabel->setString("end");
}
else
{
--_time;
_countdownLabel->setString(String::createWithFormat("%d", _time)->getCString());
}
}
方法1與方法2實現的效果完全一樣,區別在於一個使用了Lambda函數,一個使用了傳統的方法。
接下來簡單說一下scheduleOnce,這個函數用於延時執行,比如可以實現2秒後刪除自身,具體代碼如下:
scheduleOnce([this](float dt)
{
this->removeFromParent();
},2.f, "Del");
scheduleOnce是一個非常有用的函數,在很多場合都會用到。
然後再來看看scheduleUpdate,這是一個與其他函數有所區別,啓動的是一個Node::update方法,啓動之後這個方法每幀執行,而且會優先於自定義計時器執行,也可以指定優先級。
接下來我們想實現一個移動動畫,每秒鐘固定向左邊移動一定的距離,通過scheduleUpdate實現,以下是實現代碼:
bool HelloWorld::init()
{
if ( !Layer::init() )
{
return false;
}
_moveX = 100.0f;
scheduleUpdate();
}
void HelloWorld::update(float dt)
{
float moveX = _moveX * dt;
_countdownLabel->setPositionX(_countdownLabel->getPositionX() + moveX);
}
本文通過一些基礎的定時器應用分析了cocos2dx中scheduler的基本使用方法,在項目中會有更多定時器的應用場景。下一篇文章將對創建定時器的實現進行分析。