• cocos2d-x游戏开发系列教程-中国象棋02-main函数和欢迎页面


    之前两个博客讲述了象棋的规格和工程文件之后,我们继续深入的从代码开始学习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在这里是应用程序代理类,该类的作用是继承一些虚函数,对程序进行管理

    在我们的代码里,主要是

    applicationDidFinishLaunching():启动完毕时被调用

    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函数就要被自动调用了....

    预知后事如何,请听下回分解

  • 相关阅读:
    为方便储户,某银行拟开发计算机储蓄系统。储户填写的存款单或取款单由业务员输入系统,如果是存款,系统记录存款人姓名、住址、存款类型、存款日期、利率等信息,并印出存款单给储户;如果是取款,系统计算利息并印出利息清单给储户。 写出问题定义并分析系统的可行性。
    “中文编程”是解决中国程序员编程的有效武器,请问它是个“银弹”吗?
    这是我第一个博客
    jupyter-notebook打不开浏览器的问题
    python购物车程序
    python 登陆小程序
    mysql备份恢复(二)
    mysql备份恢复(一)
    docker实践之创建支持ssh服务的镜像
    基于python的设计模式之创建型模型
  • 原文地址:https://www.cnblogs.com/new0801/p/6177284.html
Copyright © 2020-2023  润新知