Cocos2d-x 实例源码分析之一 主程序分析

本文深入剖析了C++游戏引擎框架中主程序的启动流程,重点讲解了main.cpp文件的功能及AppDelegate的作用,从创建AppDelegate实例到运行CCApplication,详细阐述了启动过程。同时,介绍了AppDelegate的applicationDidFinishLaunching函数,该函数实例化导演类、设置场景和层,并开始场景,从而启动游戏引擎。进一步解释了如何通过Controller类及其子类(如TestController)实现菜单功能,包括实例菜单、关闭按钮、场景切换等关键操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  这篇文章主要是介绍主程序的框架,他理所有的实例程序,提供相应的控制。我们都知道C++的程序都是从main函数开始启动,咱们先来看一下main.cpp

#include "main.h"
#include "AppDelegate.h"
#include "CCEGLView.h"

USING_NS_CC;

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    //这个地方呢具体意义我是不太懂,功能是创建一个AppDelegate的一个实例并让他跑起来的
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();
	//设置窗口的标题
    eglView->setViewName("TestCpp");
	//设置窗口的大小
    eglView->setFrameSize(960, 640);
    return CCApplication::sharedApplication()->run();
}
代码不多,他是启动CCApplication,而AppDelegate是CCApplication,所以说他启动的是AppDelegate。总结一句话就是启动AppDelegate。

AppDelegate从函数applicationDidFinishLaunching开始执行。

bool AppDelegate::applicationDidFinishLaunching()
{
    // 实例化导演类并设置一些参数
    CCDirector *pDirector = CCDirector::sharedDirector();
    pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());

    CCSize screenSize = CCEGLView::sharedOpenGLView()->getFrameSize();

   // CCSize designSize = CCSizeMake(2880, 1920);
	CCSize designSize = CCSizeMake(720, 480);
    CCFileUtils* pFileUtils = CCFileUtils::sharedFileUtils();
    
    if (screenSize.height > 320)
    {
        CCSize resourceSize = CCSizeMake(1440, 960);
        std::vector<std::string> searchPaths;
        searchPaths.push_back("hd");
        pFileUtils->setSearchPaths(searchPaths);
        pDirector->setContentScaleFactor(resourceSize.height/designSize.height);
    }

    CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionNoBorder);

    // turn on display FPS
    pDirector->setDisplayStats(true);

    // set FPS. the default value is 1.0/60 if you don't call this
    pDirector->setAnimationInterval(1.0 / 60);
	//实例化一个CCScene(场景)
    CCScene * pScene = CCScene::create();
	//实例化一个CCLayer(层)
    CCLayer * pLayer = new TestController();
	//设置自动释放(和JAVA里的回收机制是一样的,一个对象不用了,他会自动释放内存)
    pLayer->autorelease();
	//将层添加到场景里
    pScene->addChild(pLayer);
	//最后是开始场景(就像演京剧时候似的,两边帘子退向两边,演出开始)
    pDirector->runWithScene(pScene);

    return true;
}

这个函数总的来说就是实例化一个层和一个场景,把层添加到场景里,然后开始场景。

就这么开始了?!!里面那些东西呢?左下角那些数字,中间的选项,右上角的关闭按钮搁那添加的?

我们前面已经说了,实例化一个层然后把这个层添加到场景里然后开始场景。这里实例化的场景是CCScene,这是引擎提供的类,他并没有被谁继承就被实例化话了,所以说这个场景里什么也没有。这个场景就想一个黑板啥也没有。我们看到实例化层的时候,他是new了一个TestController,这个时候我们就可以断定TestController这个类继承了CCLayer并且在这个类里添加了上面那些我们需要的东西。

在Controller.h里我们可以看到TestController是继承CCLayer的。我们来看一下Controller.cpp里的东西

static TestScene* CreateTestScene(int nIdx)
{
    CCDirector::sharedDirector()->purgeCachedData();

    TestScene* pScene = NULL;

    switch (nIdx)
    {
    case TEST_ACTIONS:
        pScene = new ActionsTestScene(); break;
    case TEST_TRANSITIONS:
        pScene = new TransitionsTestScene(); break;
     case TEST_PROGRESS_ACTIONS:
     //省略部分代码
    default:
        break;
    }

    return pScene;
}
首先是一个静态函数CreateTestScene,他接收一个int类型的参数,返回一个TestScene。可以想到我们可以用这个函数来获得场景的,就是我们点击中间的菜单,跳转到相应的界面时,这个函数会创建我们要去的那个场景的。传入一个int值,他会返回相应的场景。

接下来是TestController的构造函数

TestController::TestController()
: m_tBeginPos(CCPointZero)
{
    // 添加关闭菜单,就是右上角那个
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(s_pPathClose, s_pPathClose, this, menu_selector(TestController::closeCallback) );
    CCMenu* pMenu =CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition( CCPointZero );
    pCloseItem->setPosition(ccp( VisibleRect::right().x - 30, VisibleRect::top().y - 30));



    // 添加中间小实例的菜单  
    m_pItemMenu = CCMenu::create();
    for (int i = 0; i < TESTS_COUNT; ++i)
    {
		//g_aTestNames可以看作是一个字符串数组,里面是菜单里要显示的文字
        CCLabelTTF* label = CCLabelTTF::create(g_aTestNames[i].c_str(), "Arial", 24);     
        CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestController::menuCallback));
        m_pItemMenu->addChild(pMenuItem, i + 10000);
        pMenuItem->setPosition( ccp( VisibleRect::center().x, (VisibleRect::top().y - (i + 1) * LINE_SPACE) ));
    }

    m_pItemMenu->setContentSize(CCSizeMake(VisibleRect::getVisibleRect().size.width, (TESTS_COUNT + 1) * (LINE_SPACE)));
    m_pItemMenu->setPosition(s_tCurPos);
	//添加实例菜单到Layer
    addChild(m_pItemMenu);
    setTouchEnabled(true);
	//添加关闭按钮到Layer
    addChild(pMenu, 1);

}

      在这个构造函数里,我们创建了实例菜单和关闭按钮并把他们加到了Layer上。

但是当我们点击其中一个菜单项的时候,他会做什么呢?我们看到在创建每一个子菜单时,我们都设置了回调函数

CCMenuItemLabel* pMenuItem = CCMenuItemLabel::create(label, this, menu_selector(TestController::menuCallback));
menuCallBack就是回调函数,但菜单被点击时,这个函数就会执行。

下面我们来看一下这个回调函数

void TestController::menuCallback(CCObject * pSender)
{
    // 获取被点击的子菜单项,
    CCMenuItem* pMenuItem = (CCMenuItem *)(pSender);
	//获取子菜单项的Zorder值,这个值就是在Z轴上的一个值,通过设置他可以影响遮挡关系
	//这里呢,子菜单之间是没有遮挡关系的,这个值其实就是用来获取这个子菜单对应场景的index值
    int nIdx = pMenuItem->getZOrder() - 10000;

    // 通过静态方法CreateTestScene获得相应的场景并开始场景
    TestScene* pScene = CreateTestScene(nIdx);
    if (pScene)
    {
        pScene->runThisTest();
        pScene->release();
    }
}
同理我们可理解关闭按钮的回调函数closeCallback。

ccTouchesBegan和ccTouchesMoved实现了上下拖动实例菜单,这里我们不在讲述。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值