之前兩個博客講述了象棋的規格和工程文件之后,我們繼續深入的從代碼開始學習cocos2dx
首先從程序入口main函數開始
main函數
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{UNREFERENCED_PARAMETER(hPrevInstance);UNREFERENCED_PARAMETER(lpCmdLine);#ifdef USE_WIN32_CONSOLEAllocConsole();freopen("CONIN$", "r", stdin);freopen("CONOUT$", "w", stdout);freopen("CONOUT$", "w", stderr);
#endif// create the application instanceAppDelegate app;// 獲得viewCCEGLView* eglView = CCEGLView::sharedOpenGLView();eglView->setFrameSize(480, 320);// 運行程序int ret = CCApplication::sharedApplication()->run();#ifdef USE_WIN32_CONSOLEFreeConsole();
#endifreturn ret;
}
以上是中國象棋的main函數的所有內容,掐掉不關注的內容,關鍵部位為以下代碼:
// create the application instanceAppDelegate app;// 獲得viewCCEGLView* eglView = CCEGLView::sharedOpenGLView();eglView->setFrameSize(480, 320);// 運行程序int ret = CCApplication::sharedApplication()->run();
步驟:1.使用AppDelegate去創建app對象
2.創建視圖對象比設置視圖對象
3.讓app運行起來
在這里可以看到app對象并沒有被顯式的使用,但是它必須定義,在它的構造函數里,會將app的指針
保存在全局變量,使得CCApplication::sharedApplication()能獲得app指針。
怎么驗證這點呢,我們可以看到AppDelegate是有CCAppplication派生,而在CCApplication的構造函數里
有如下代碼:
AppDelegate
AppDelegate在這里是應用程序代理類,該類的作用是繼承一些虛函數,對程序進行管理
在我們的代碼里,主要是
applicationDidEnterBackground():當程序進入后臺時該函數被調用
applicationWillEnterForeground():當程序從后臺進入前臺時被調用
這三個函數我們重點看第一個吧,因為我們在windows下,后面兩個函數無效,先學習第一個
看看第一個函數的內容:
bool AppDelegate::applicationDidFinishLaunching()
{// initialize directorCCDirector *pDirector = CCDirector::sharedDirector(); // 導演類pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); // 給導演一個空間// turn on display FPSpDirector->setDisplayStats(false); // 顯示view // create a scene. it's an autorelease objectCCScene *pScene = CCWelCome::scene(); // 創建一個WelCome場景// 讓導演去運行這個WelCome場景,該welCome場景是象棋程序里的第一個場景// 第一個場景有什么內容呢?那我們應該去看CCWelCome::scene();pDirector->runWithScene(pScene); return true;
}
在這個函數里,創建了一個導演對象pDirector,然后給導演一個空間pDirecotor->setOpenGLView(...);而這個view明顯就是在main函數里創建的那個view,這個view是一個物理上的窗口,控制著整個程序的顯示位置。
接下來CCWelCome::scene創建了一個場景,場景和view是什么關系呢?就好像馬戲團表演節目,可以在北京表演可以在上海表演
無論你在哪里表演,你總得先搭臺子,這個臺子就是view,臺子的位置決定了你在哪里表演節目。而當一個節目上演的時候
這個叫做scene,WelCome就是象棋里面的一個場景。
接著讓導演pDirecotor去演示該Scene。該Sence演示的結果如下:
同學們一定好奇,這個歡迎頁面怎么出來的,那我們繼續看WelCome.cpp
CCWelCome
先看頭文件的類定義:
class CCWelCome : public CCLayer
{
public:static CCScene* scene();virtual bool init();void step(float dt);CREATE_FUNC(CCWelCome);
};
從類定義可以看出CCWelCome是一個CCLayer,它有四個函數scene函數:該函數為CWelCome創建了一個scene并創建一個CWelCome放入到該sence中
init函數:該函數被自動調用,CWelCome中的元素,都是在init時候被創建的
step函數:該函數在init時設置被計劃調用,也就是當init被調用后一段時間,step被調用了
CREATE_FUNC:其實是定義了一個create函數
scene函數:
CCScene* CCWelCome::scene()
{// 創建一個新的sceneCCScene* pScene = CCScene::create();if(!pScene){return NULL;}// 創建一個新CLayerCCWelCome* pLayer = CCWelCome::create();if(!pLayer){return NULL;}// 把Layer加入到Scene,返回Scene,所以scene函數時創建了一個Layer但是返回包容了該Layer的一個ScenepScene->addChild(pLayer);return pScene;
}
注釋在代碼中,同學可以好好看。這里注意為什么要返回Scene,為什么不直接返回Layer,是因為導演只能導Scene。那么WelCome作為一個Layer,只好將其加入到一個Scene之后再返回。
init函數:
bool CCWelCome::init()
{// 調用父類的init函數進行初始化if (!CCLayer::init()){// 如果調用父類的初始化就失敗,則返回falsereturn false;}// 獲得窗口大小,這里CCDirector::sharedDirector獲取的導演是外面創建的那個// 精靈需要用到這個位置信息CCSize s = CCDirector::sharedDirector()->getWinSize();// 創建兩個精靈,第一個是黑色的老將,第二個是紅帥,都通過addChild把精靈加入到了本Layer// 兩個精靈的位置是由上述窗口Size計算得到,圖片bkg1.png和bkg2.png是兩個老將的圖片,如果// 在你的環境中不顯示,那就要看看RES_PATH的路徑是否正確了CCSprite* pBlackSprite = CCSprite::create(RES_PATH"bkg1.png");pBlackSprite->setPosition(ccp(s.width/2 - 56, s.height/2));addChild(pBlackSprite, 1); CCSprite* pRedSprite = CCSprite::create(RES_PATH"bkg2.png");pRedSprite->setPosition(ccp(s.width/2 + 56, s.height/2));addChild(pRedSprite, 2); // 最后精靈放置好之后,調用定時器函數,在一秒之后調用step函數schedule(schedule_selector(CCWelCome::step), 1.0f);return true;
}
在WelCome層中,我們為該Layer創建了兩個精靈后,啟動定時器,1秒之后調用step函數,使得窗口停留一秒后進入比賽窗口,那是如何進入比賽窗口的呢。我們需要看step函數
step函數:
void CCWelCome::step(float dt)
{// 比賽界面的SceneCCScene* pScene = CCMainMenu::scene();// 做個特效,逐漸隱退效果CCScene* ps = CCTransitionFade::create(2, pScene, ccc3(0, 0, 0));//CCScene* ps = pScene; // 如果把上面的話,換成這句,那么場景切換就很生硬了// 替換senceCCDirector::sharedDirector()->replaceScene(ps);// step函數的定時器取消掉unschedule(schedule_selector(CCWelCome::step));
}
step函數創建新的主界面場景,然后在場景切換時做了個特效,接著將新的sence替換那個WelCome的Scene。這樣CCMainMenu的init函數就要被自動調用了....
預知后事如何,請聽下回分解