我們就從最開始的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中的一個宏函數。
它的定義是這樣的:(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