cocos2d-x 4.0 學習之路(四)簡單學習HelloWorld代碼

我們就從最開始的HelloWorld代碼開始學習吧。
那麼HelloWorld窗口是怎麼顯示出來的呢?我們得找到入口程序,當然是Main函數了。下面是HelloWorld的工程目錄:
在這裏插入圖片描述
打開main.cpp,裏面就2行代碼,實際上的入口是Classes\AppDelegate.cpp
在這裏插入圖片描述

AppDelegate.cpp

裏面有一個applicationDidFinishLaunching()方法,這個纔是程序的真正的入口(也是跨平臺的入口,關於cocos如何跨平臺,請自行搜索)。解讀一下代碼:
1.進來就定義了一個Director(導演)。

// initialize director
auto director = Director::getInstance();

這個導演的角色非常厲害,其實和現實中的導演是一樣的。所有要出演的場景、演員、背景、音樂等都需要導演來控制。那麼接下來,導演幹了很多事情,我挑主要的寫:
2. director->setDisplayStats(true); 設置是否顯示遊戲的幀數等調試信息。(也就是HelloWorld畫面左下角的那些數字信息)
3. director->setAnimationInterval(1.0f / 60); 設置遊戲的幀率,每秒60幀。啥是幀率呢,其實遊戲世界都是一幅幅靜止的畫面在不斷的變換,而讓人感覺是動畫的錯覺。那麼每一幅畫面就是一幀,那麼這個設定就是1秒可以切換60個畫面。
4. director->setContentScaleFactor(); 設置分辨率。會有多個分支來判斷你要顯示的介質是多大尺寸的,分辨率可會跟着設定成不同的。是不是挺智能啊。
5. auto scene = HelloWorld::createScene(); 做成HelloWorld場景的實例。我們HelloWorld畫面上的各種圖片、菜單,標籤等,都是在這裏被生成的。
6. director->runWithScene(scene); 註釋很清楚明瞭run。就是導演讓HelloWorld這個場景跑起來!

默認窗體的尺寸跑起來,窗體顯示比較小,那我們想讓窗體大一些怎麼弄呢?修改這個的地方就可以了:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32) || (CC_TARGET_PLATFORM == CC_PLATFORM_MAC) || (CC_TARGET_PLATFORM == CC_PLATFORM_LINUX)
        glview = GLViewImpl::createWithRect("HelloWorld", cocos2d::Rect(0, 0, designResolutionSize.width, designResolutionSize.height));

在這裏插入圖片描述
Ctrl+F5運行一下,是不是窗體變大了,分辨率也高了。那麼我們之後往裏面加東西看着也方便。

HelloWorldScene.cpp

接下來,纔到HelloWorld的畫面世界。
從AppDelegate我們知道,HelloWorld是用createScene()方法生成的。

Scene* HelloWorld::createScene()
{
    return HelloWorld::create();
}

那麼HelloWorld::create(); 執行的,是HelloWorldScene.h中的一個宏函數。
HelloWorldScene.h
它的定義是這樣的:(platform/CCPlatformMacros.h)

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

簡單來說,宏函數就是在編譯的時候,把參數__TYPE__,替換成你傳入的值,這裏是HelloWorld。那麼編譯的時候,就是編譯的下面的代碼:

static HelloWorld* create() 
{ 
    HelloWorld *pRet = new(std::nothrow) HelloWorld(); 
    if (pRet && pRet->init()) 
    { 
        pRet->autorelease(); 
        return pRet; 
    } 
    else 
    { 
        delete pRet; 
        pRet = nullptr; 
        return nullptr; 
    } 
}

那麼create()裏面做了什麼呢, 就是定義了一個HelloWorld的實例,並且執行它的初始化函數pRet->init()
好,那我們到HelloWorld的Init()方法裏面看看吧:
1.調用父類初始化方法,因爲HelloWorldScene是繼承於Scene的。

bool HelloWorld::init()
{
    //////////////////////////////
    // 1. super init first
    if ( !Scene::init() )
    {
        return false;
    }
	......
}

2.加了一個關閉按鈕(MenuItemImage::create)。即畫面右下角的這個圖標。
在這裏插入圖片描述在這裏插入圖片描述
普通的時候顯示CloseNormal.png,當鼠標放上去的時候會顯示CloseSelected.png。(工程裏的圖片等文件,都在Resource文件夾裏。)

    /////////////////////////////
    // 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
    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));

    if (closeItem == nullptr ||
        closeItem->getContentSize().width <= 0 ||
        closeItem->getContentSize().height <= 0)
    {
        problemLoading("'CloseNormal.png' and 'CloseSelected.png'");
    }
    else
    {
        float x = origin.x + visibleSize.width - closeItem->getContentSize().width/2;
        float y = origin.y + closeItem->getContentSize().height/2;
        closeItem->setPosition(Vec2(x,y));
    }

    // create menu, it's an autorelease object
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Vec2::ZERO);
    this->addChild(menu, 1);

之後又設定了一個回調函數,CC_CALLBACK_1(HelloWorld::menuCloseCallback, this),實現了按鈕被點擊的動作(關閉程序)。
接下來是設定這個按鈕的位置closeItem->setPosition(Vec2(x,y));在右下角。
最後,把這個Menu添加到HelloWorld這個場景中:this->addChild(menu, 1);

總結一下增加控件的流程:
a. 實例化一個控件XXX::create(),裏面設定好圖片,有動作的設定好回調函數
b. 設置顯示的位置setPosition()。這個就自己計算吧
c. 添加到場景中this->addChild()

3.接下來的代碼就比較容易理解了:添加了一個Label和一個精靈(Sprite)。
Label顯示的是HelloWorld。 精靈顯示的是cocos的小精靈圖標。
都是上面提到的流程。

// add a label shows "Hello World"
    // create and initialize a label

    auto label = Label::createWithTTF("Hello World", "fonts/Marker Felt.ttf", 24);
    if (label == nullptr)
    {
        problemLoading("'fonts/Marker Felt.ttf'");
    }
    else
    {
        // position the label on the center of the screen
        label->setPosition(Vec2(origin.x + visibleSize.width/2,
                                origin.y + visibleSize.height - label->getContentSize().height));

        // add the label as a child to this layer
        this->addChild(label, 1);
    }

    // add "HelloWorld" splash screen"
    auto sprite = Sprite::create("HelloWorld.png");
    if (sprite == nullptr)
    {
        problemLoading("'HelloWorld.png'");
    }
    else
    {
        // position the sprite on the center of the screen
        sprite->setPosition(Vec2(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

        // add the sprite as a child to this layer
        this->addChild(sprite, 0);
    }

以上,就是HelloWorld畫面的製作和顯示過程了。

那麼,上面各種控件的使用方法,我們可以參考官方的文檔
在這裏插入圖片描述
你可以在搜索欄,輸入比如Label,就可以找個Label的介紹:
在這裏插入圖片描述
在這裏插入圖片描述
以上的文檔只是簡單的說明文檔,詳細API使用的記載,你還得參考API文檔
在這裏插入圖片描述

The End

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章