4.帧循环(游戏主循环),schedule
1 概述
游戲乃至圖形界面的本質是不斷地繪圖,然而繪圖并不是隨意的,任何游戲都需要遵循一定的規則來呈現出來,這些規則就體現為游戲邏輯。游戲邏輯會控制游戲內容,使其根據用戶輸入和時間流逝而改變。因此,游戲可以抽象為不斷地重復。
2 以下動作:
A 處理用戶輸入
B 處理定時事件
C 繪圖
游戲主循環就是這樣的一個循環,它會反復執行以上動作,保持游戲進行下去,直到玩家退出游戲。
CCDirector::mainLoop()方法,這個方法負責調動定時器,繪圖,發送全局通知,并處理內存回收池。該方法按幀調用,每幀調用一次,而幀間間隔取決于兩個因素,一個是預設的幀率,默認為60幀每秒:另一個是每幀的計算大小。當邏輯處理與繪圖計算過大時,設備無法完成每秒60次繪制,此時幀率就會降低。
3 實現
mainLoop()方法是定義在CCDirector中的抽象方法,它的實現位于同一個文件中的CCDisplayLinkDirector類。代碼如下:
上述代碼主要包含如下3個步驟。
判斷是否需要釋放CCDirector,如果需要,則刪除CCDirector占用的資源,通常,游戲結束時才會執行這個步驟。
調用drawScene()發方法,繪制當前場景并進行其他必要的處理。
彈出自動回收池,使得這一幀被放入自動回收池的對象全部釋放。
?
在主循環中drawScene(),主要進行3個操作:
調用了定時調度器的update方法,引發定時器事件。
如果場景需要被切換,則調用setNextStage方法,在顯示場景前切換場景。
調用當前場景的visit方法,繪制當前場景。
4 定時器
| Schedule.h |
| #ifndef __Schedule_H__ #define __Schedule_H__ ? #include "cocos2d.h" USING_NS_CC; class Schedule :public CCLayer { public: ??? static CCScene * scene(); ??? CREATE_FUNC(Schedule); ??? bool init(); ? ??? void update(float) override; ? ??? void mySchedule(float dt); }; ? #endif |
| Schedule.cpp |
| #include "Schedule.h" #include "AppMacros.h" ? CCScene *Schedule::scene() { ??? CCScene * scene = CCScene::create(); ??? Schedule * layer = Schedule::create(); ??? scene->addChild(layer); ??? return scene; } ? bool Schedule::init() { ??? CCLayer::init(); ??? //scheduleUpdate(); ??? //unscheduleUpdate(); ? ??? //scheduleOnce(schedule_selector(Schedule::mySchedule), 2); ??? schedule(schedule_selector(Schedule::mySchedule)); ??? //功能等同scheduleUpdate();回調函數可以自定義 ??? //schedule(schedule_selector(Schedule::mySchedule), 3); ??? //CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay); ??? //schedule(schedule_selector(Schedule::mySchedule),1,10,4); ??? //4s以后,每隔1s執行一次回調,共執行10次 ? ??? CCSprite * spr = CCSprite::create("p_2_01.png"); ??? spr->setPosition(ccp(100,winSize.height / 2)); ??? addChild(spr); ??? spr->setTag(100); ? ??? //CCMoveBy * by = CCMoveBy::create(2, ccp(300, 0)); ??? //CCMoveBy * by1 = (CCMoveBy *)by->reverse(); ??? //CCSequence *seq = CCSequence::create(by, by1, NULL); ??? //spr->runAction(CCRepeatForever::create(seq)); ? ??? return true; } ? void Schedule::update(float dt) { ??? CCLOG("dt = %g",dt); ??? static int i = 0; ??? i++; ??? if (i == 120) ??? { ??????? //結束定時器 ??????? unscheduleUpdate(); ??????? CCLog("schedule is over"); ??? } } ? void Schedule::mySchedule(float dt) { ??? CCSprite * spr = (CCSprite *)getChildByTag(100); ??? float v = 300 / 2; ? ??? static int count = 0; ??? count++; ? ??? static bool flag = true; ??? if (flag) ??? { ??????? if ((spr->getPositionX() + v*dt) < 400) ??????? { ??????????? spr->setPositionX(spr->getPositionX() + v*dt); ??????? } ??????? else ??????? { ??????????? flag = !flag; ??????? } ??? } ??? if (!flag) ??? { ??????? if ((spr->getPositionX() - v*dt) > 100) ??????? { ??????????? spr->setPositionX(spr->getPositionX() - v*dt); ??????? } ??????? else ??????? { ??????????? flag = !flag; ??????? } ??? } ? ??? if (count == 1000) ??? { ??????? unschedule(schedule_selector(Schedule::mySchedule)); ??? } } |
| 運行結果:
|
?
5 定時器Schedule
A 幀循環定時器
| scheduleUpdate();//幀循環定時器,每一幀都會被調動,對實時性要求非常高的,比如碰撞檢測 void update(float delta); unscheduleUpdate();//關閉定時器 |
B 一次性定時器
參數解析:
| scheduleOnce(SEL_SCHEDULE selector, float delay) //第一個參數表示要回調的函數,第二個參數表示延時 |
| typedef void (CCObject::*SEL_SCHEDULE)(float); #define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR); |
| scheduleOnce (schedule_selector(Schedule::updateOnce),2); void updateOnce(float delta); |
?
C 自定義定時器
自定義定時器有3個重載函數,底層都默認調用了scheduleSelector,它的幾個參數分別表示,scheduleSelector回調函數,interval時間間隔,repeat重復次數,delay延時執行。
| void CCNode::schedule(SEL_SCHEDULE selector) { this->schedule(selector, 0.0f, kCCRepeatForever, 0.0f); } ? /本質同scheduleUpdate 但是可以自己寫回調函數 void CCNode::schedule(SEL_SCHEDULE selector, float interval) { this->schedule(selector, interval, kCCRepeatForever, 0.0f); } ? void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay){ m_pScheduler->scheduleSelector(selector, this, interval , repeat,delay, !m_bRunning); } |
?
D 定時器停止
| void CCNode::unschedule(SEL_SCHEDULE selector); void CCNode::unscheduleAllSelectors(); |
注意:多個定時器,可并存,可彼此開始與停止。
?
?
?
?
?
?
?
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的4.帧循环(游戏主循环),schedule的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自离有工资吗 有困扰的进来看看解答
- 下一篇: 办浦发银行的储蓄卡需要什么