cocos2d究竟如何开始的?

本文详细介绍了如何使用Cocos2d游戏引擎进行游戏开发,包括理解Cocos2d的基本概念,如导演、场景、精灵等,并通过HelloWorld示例展示了如何创建简单的游戏界面。此外,文章还探讨了Cocos2d的初始化过程、内存管理以及消息循环实现,旨在为初学者提供清晰的入门指南。

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

今天忙于学校的招聘,我发现招聘游戏互联网公司来学校的挺少的,而限定cocos2d 开发的也比较少,但是这不一定就意味着我要放弃这个行业。

 

不废话了。

 

今天主要看了下cocos2d怎么使用吧。

 

Cocos2d 这个游戏引擎还是很好上手的。

 

我看的书

 

 

 首先要理解

1.CCDirector导演就是负责CCScene怎么显示啊,等等,导演就是看场景的也可以很好的理解

2.CCScene感觉就像容器,里面装各种CCLayer

3.CCSprite是处理角色或者背景,精灵对象

4.CCMenuCCMenuItem 也很简单 不用解释了,里面还有参数是函数地址的,也就是回调函数、感觉也比较简单。具体都是什么selector;

 

上面的大部分类都是继承CCNode 

 

我猜:

这里有个设计模式,可以参考c++可复用的设计模式,组件模式,个人感觉有点像,具体代码没有深究

来看下cocos2d HelloWorld的代码;

 

class HelloWorld : public cocos2d::CCLayer
{
public:
    // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone
    virtual bool init();  
 
    // there's no 'id' in cpp, so we recommend returning the class instance pointer
    static cocos2d::CCScene* scene();
    
    // a selector callback
    void menuCloseCallback(CCObject* pSender);
    
    // implement the "static node()" method manually
    CREATE_FUNC(HelloWorld);
};

看起来都挺简单,不用解释什么,这里有个宏也看看,CREATE_FUNC

去看看定义,

 

#define CREATE_FUNC(__TYPE__) \
static __TYPE__* create() \
{ \
    __TYPE__ *pRet = new __TYPE__(); \
    if (pRet && pRet->init()) \
    { \
        pRet->autorelease(); \
        return pRet; \
    } \
    else \
    { \
        delete pRet; \
        pRet = NULL; \
        return NULL; \
    } \
}

咦,不错哦,cocos2d还帮我自动调用init(),自动调用autorelease()

那这样我只要专注于init出事化代码了,内存也不用关心了,

 

来具体看下init

 

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !CCLayer::init() )
    {
        return false;
    }
    
    CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize();
    CCPoint origin = CCDirector::sharedDirector()->getVisibleOrigin();
 
    /////////////////////////////
    // 2. add a menu item with "X" image, which is clicked to quit the program
    //    you may modify it.
 
    // add a "close" icon to exit the progress. it's an autorelease object
    CCMenuItemImage *pCloseItem = CCMenuItemImage::create(
                                        "CloseNormal.png",
                                        "CloseSelected.png",
                                        this,
                                        menu_selector(HelloWorld::menuCloseCallback));
    
pCloseItem->setPosition(ccp(origin.x + visibleSize.width - pCloseItem->getContentSize().width/2 ,
                                origin.y + pCloseItem->getContentSize().height/2));
 
    // create menu, it's an autorelease object
    CCMenu* pMenu = CCMenu::create(pCloseItem, NULL);
    pMenu->setPosition(CCPointZero);
    this->addChild(pMenu, 1);
 
    /////////////////////////////
    // 3. add your codes below...
 
    // add a label shows "Hello World"
    // create and initialize a label
    
    CCLabelTTF* pLabel = CCLabelTTF::create("Hello World", "Arial", 24);
    
    // position the label on the center of the screen
    pLabel->setPosition(ccp(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - pLabel->getContentSize().height));
 
    // add the label as a child to this layer
    this->addChild(pLabel, 1);
 
    // add "HelloWorld" splash screen"
    CCSprite* pSprite = CCSprite::create("HelloWorld.png");
 
    // position the sprite on the center of the screen
    pSprite->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));
 
    // add the sprite as a child to this layer
    this->addChild(pSprite, 0);
    
    return true;
}


 

咋一看,代码有点多,不过就是父类初始化,菜单,背景啊什么的,设置设置位置,不复杂。

 

可是,代码是怎么运行的呢?

 

看看main在哪里。

 

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR    lpCmdLine,
                       int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);
 
    // create the application instance
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();
    eglView->setViewName("Mota");
    eglView->setFrameSize(480, 320);
    return CCApplication::sharedApplication()->run();
}


 

封装的真心不错,声明了一个app 还是代理类的app 我猜,肯定完成了很多初始化的任务。具体看看去。

 

class  AppDelegate : private cocos2d::CCApplication
{
public:
    AppDelegate();
    virtual ~AppDelegate();
 
    /**
    @brief    Implement CCDirector and CCScene init code here.
    @return true    Initialize success, app continue.
    @return false   Initialize failed, app terminate.
    */
    virtual bool applicationDidFinishLaunching();
 
    /**
    @brief  The function be called when the application enter background
    @param  the pointer of the application
    */
    virtual void applicationDidEnterBackground();
 
    /**
    @brief  The function be called when the application enter foreground
    @param  the pointer of the application
    */
    virtual void applicationWillEnterForeground();
};


 

真心继承了CCApplication,只是重写了几个方法, 

 

 /**
    @brief    Implement CCDirector and CCScene init code here.
    @return true    Initialize success, app continue.
    @return false   Initialize failed, app terminate.
    */
    virtual bool applicationDidFinishLaunching();


 

这个方法简介不错,仔细瞧瞧,

 

bool AppDelegate::applicationDidFinishLaunching() {
    // initialize director
    CCDirector* pDirector = CCDirector::sharedDirector();
    CCEGLView* pEGLView = CCEGLView::sharedOpenGLView();
 
    pDirector->setOpenGLView(pEGLView);
    // 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);
 
    // create a scene. it's an autorelease object
    CCScene *pScene = HelloWorld::scene();
 
    // run
    pDirector->runWithScene(pScene);
 
    return true;
}


 

好像,我刚刚的HelloWorld 用到了,这里就是初始化了么, 

 

runWithScene() 是怎么样的方法?

 

敲敲去。

 

 pushScene(pScene);

 startAnimation();

 

看了下,里面有个CCSceneStack 

startAnimation()又干嘛了?

 

void CCDisplayLinkDirector::startAnimation(void)
{
    if (CCTime::gettimeofdayCocos2d(m_pLastUpdate, NULL) != 0)
    {
        CCLOG("cocos2d: DisplayLinkDirector: Error on gettimeofday");
    }
 
    m_bInvalid = false;
#ifndef EMSCRIPTEN
    CCApplication::sharedApplication()->setAnimationInterval(m_dAnimationInterval);
#endif // EMSCRIPTEN
}


 

里面好像没有什么重要的东西哦!我怎么没看到循环呢,等等,主函数中还有一个方法,

 

CCApplication::sharedApplication()->run();

 

具体是什么呢,看看去吧~

 

 

int CCApplication::run()
{
    PVRFrameEnableControlWindow(false);
 
    // Main message loop:
    MSG msg;
    LARGE_INTEGER nFreq;
    LARGE_INTEGER nLast;
    LARGE_INTEGER nNow;
 
    QueryPerformanceFrequency(&nFreq);
    QueryPerformanceCounter(&nLast);
 
    // Initialize instance and cocos2d.
    if (!applicationDidFinishLaunching())
    {
        return 0;
    }
 
    CCEGLView* pMainWnd = CCEGLView::sharedOpenGLView();
    pMainWnd->centerWindow();
    ShowWindow(pMainWnd->getHWnd(), SW_SHOW);
 
    while (1)
    {
        if (! PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            // Get current time tick.
            QueryPerformanceCounter(&nNow);
 
            // If it's the time to draw next frame, draw it, else sleep a while.
            if (nNow.QuadPart - nLast.QuadPart > m_nAnimationInterval.QuadPart)
            {
                nLast.QuadPart = nNow.QuadPart;
                CCDirector::sharedDirector()->mainLoop();
            }
            else
            {
                Sleep(0);
            }
            continue;
        }
 
        if (WM_QUIT == msg.message)
        {
            // Quit message loop.
            break;
        }
 
        // Deal with windows message.
        if (! m_hAccelTable || ! TranslateAccelerator(msg.hwnd, m_hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
 
    return (int) msg.wParam;
}


 

一目了然,so easy windows的消息循环在这里了!!看看什么,就是while 循环嘛,然后还设置了下帧数!!不是很简单!!??

 

今天就看到这里吧!这个引擎真的不难!

简单粗暴,就是好!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值