之前两个博客讲述了象棋的规格和工程文件之后,我们继续深入的从代码开始学习cocos2dx
首先从程序入口main函数开始
main函数
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER(hPrevInstance); UNREFERENCED_PARAMETER(lpCmdLine); #ifdef USE_WIN32_CONSOLE AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); #endif // create the application instance AppDelegate app; // 获得view CCEGLView* eglView = CCEGLView::sharedOpenGLView(); eglView->setFrameSize(480, 320); // 运行程序 int ret = CCApplication::sharedApplication()->run(); #ifdef USE_WIN32_CONSOLE FreeConsole(); #endif return ret; }
以上是中国象棋的main函数的所有内容,掐掉不关注的内容,关键部位为以下代码:
// create the application instance AppDelegate app; // 获得view CCEGLView* 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 director CCDirector *pDirector = CCDirector::sharedDirector(); // 导演类 pDirector->setOpenGLView(CCEGLView::sharedOpenGLView()); // 给导演一个空间 // turn on display FPS pDirector->setDisplayStats(false); // 显示view // create a scene. it's an autorelease object CCScene *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() { // 创建一个新的scene CCScene* pScene = CCScene::create(); if(!pScene) { return NULL; } // 创建一个新CLayer CCWelCome* pLayer = CCWelCome::create(); if(!pLayer) { return NULL; } // 把Layer加入到Scene,返回Scene,所以scene函数时创建了一个Layer但是返回包容了该Layer的一个Scene pScene->addChild(pLayer); return pScene; }注释在代码中,同学可以好好看。这里注意为什么要返回Scene,为什么不直接返回Layer,是因为导演只能导Scene。
那么WelCome作为一个Layer,只好将其加入到一个Scene之后再返回。
init函数:
bool CCWelCome::init() { // 调用父类的init函数进行初始化 if (!CCLayer::init()) { // 如果调用父类的初始化就失败,则返回false return 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) { // 比赛界面的Scene CCScene* pScene = CCMainMenu::scene(); // 做个特效,逐渐隐退效果 CCScene* ps = CCTransitionFade::create(2, pScene, ccc3(0, 0, 0)); //CCScene* ps = pScene; // 如果把上面的话,换成这句,那么场景切换就很生硬了 // 替换sence CCDirector::sharedDirector()->replaceScene(ps); // step函数的定时器取消掉 unschedule(schedule_selector(CCWelCome::step)); }step函数创建新的主界面场景,然后在场景切换时做了个特效,接着将新的sence替换那个WelCome的Scene。
这样CCMainMenu的init函数就要被自动调用了....
预知后事如何,请听下回分解