helloworld讲解cocos2d-x的编程思路与要点
用helloworld講解cocos2d-x的編程思路與要點(diǎn)
本文以cocos2d-x的helloworld為例,講解cocos2d-x引擎的特點(diǎn)和要點(diǎn),2.2為了展示新功能,把包括屏幕自適應(yīng)在內(nèi)的新特性相關(guān)代碼加入了helloworld工程代碼里,但是也增加新人的上手難度,我會(huì)避過不談,只說關(guān)鍵的幾句代碼,對(duì)于已經(jīng)了解cocos2d-x架構(gòu)的朋友,本文后面的內(nèi)容對(duì)你毫無幫助,可以去關(guān)注我寫的《cocos2d-x提高篇》(不過此刻我或許還沒寫)。當(dāng)然了,不可能一開始就把所有內(nèi)容說清楚,剛上手的朋友要想做游戲抑或是寫例子,首先要理解下兩個(gè)要點(diǎn)。
要點(diǎn)一:
關(guān)于繪制。許多朋友在剛接觸cocos2d-x的時(shí)候,迫不及待去尋找繪制函數(shù),問我有沒有類似drawimage()抑或是drawstring()這樣的函數(shù)。這里要多說幾句,cocos2d-x底層已經(jīng)對(duì)繪制進(jìn)行了簡(jiǎn)單的封裝,我們并不需要顯性的去寫drawImage()這樣的函數(shù)。
對(duì)于這點(diǎn)該如何理解呢?譬如說我們要做一個(gè)游戲,往往會(huì)把邏輯層和繪制層分開。在邏輯層,可能有很多關(guān)卡,但是當(dāng)前玩家只有一個(gè)關(guān)卡,關(guān)卡里有地圖也有許多敵兵。我們?cè)谶壿媽舆M(jìn)行邏輯運(yùn)算,更改敵兵的狀態(tài)和坐標(biāo)。之后再在繪制層把屏幕里的敵兵以及地圖的可見區(qū)域畫到屏幕上。這就是經(jīng)典的(邏輯-繪制-邏輯-繪制)結(jié)構(gòu)。
而對(duì)于剛上手的朋友可以這么理解,cocos2d-x已經(jīng)把繪制的代碼寫好了,我們只需要在邏輯層設(shè)置。在cocos2d-x里,有scene(場(chǎng)景)的概念,當(dāng)前scene只有一個(gè),scene里有很多ccsprite(精靈),一個(gè)ccsprte有x,y,引用圖片這些屬性,Cocos2d-x會(huì)不斷的把當(dāng)前scene里的可見精靈繪制到屏幕上。因此,如果我們要在cocos2d-x里繪制一張背景圖,首先創(chuàng)建一個(gè)scene,然后創(chuàng)建一個(gè)精靈,以某種形式將其添加到scene里,設(shè)置好引用的圖片和精靈位置,最后記得將scene設(shè)置當(dāng)前場(chǎng)景就ok了。下面看代碼。
先看main.cpp
#include"main.h"
#include"../Classes/AppDelegate.h"
#include"CCEGLView.h"
USING_NS_CC;
intAPIENTRY_tWinMain(HINSTANCEhInstance,
HINSTANCEhPrevInstance,
LPTSTRlpCmdLine,
intnCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
AppDelegateapp;
CCEGLView*eglView=CCEGLView::sharedOpenGLView();
eglView->setViewName("HelloCpp");
eglView->setFrameSize(2048,1536);
eglView->setFrameZoomFactor(0.4f);
returnCCApplication::sharedApplication()->run();
}
這里我只要記住eglview->setFrameSize(w,h)函數(shù)作用是設(shè)置視圖大小
vs里的main.cpp文件是win32平臺(tái)下程序的入口,這里會(huì)創(chuàng)建一個(gè)窗口,大小為(2048,1536)
setFrameZoomFactor(0.4f)是將窗口縮小為所設(shè)大小的0.4倍,為了照顧我這樣的小屏幕用戶,不過這樣還是很蛋疼
所以我把窗口設(shè)置為480X320,屏蔽了縮放窗口那句話
再看AppDelegate.h
#ifndef_APP_DELEGATE_H_
#define_APP_DELEGATE_H_
#include"cocos2d.h"
classAppDelegate:privatecocos2d::CCApplication
{
public:
AppDelegate();
virtual~AppDelegate();
virtualboolapplicationDidFinishLaunching();
virtualvoidapplicationDidEnterBackground();
virtualvoidapplicationWillEnterForeground();
};
#endif//_APP_DELEGATE_H_
AppDelegate是程序的控制類,里面有三個(gè)函數(shù)(applicationDidFinishLaunching,applicationDidEnterBackground,applicationWillEnterForeground)
分別在程序啟動(dòng)后,程序掛起進(jìn)入后臺(tái),程序從后臺(tái)返回時(shí)執(zhí)行,定義需要我們自己實(shí)現(xiàn)。
看看AppDelegate.cpp里我們只看applicationDidFinishLaunching()是如何實(shí)現(xiàn)的
boolAppDelegate::applicationDidFinishLaunching(){
CCDirector*pDirector=CCDirector::sharedDirector();
CCEGLView*pEGLView=CCEGLView::sharedOpenGLView();
pDirector->setOpenGLView(pEGLView);
CCSizeframeSize=pEGLView->getFrameSize();
#if(CC_TARGET_PLATFORM==CC_PLATFORM_WINRT)||(CC_TARGET_PLATFORM==CC_PLATFORM_WP8)
pEGLView->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,kResolutionShowAll);
#else
pEGLView->setDesignResolutionSize(designResolutionSize.width,designResolutionSize.height,kResolutionNoBorder);
#endif
vector<string>searchPath;
if(frameSize.height>mediumResource.size.height)
{
searchPath.push_back(largeResource.directory);
pDirector->setContentScaleFactor(MIN(largeResource.size.height/designResolutionSize.height,largeResource.size.width/designResolutionSize.width));
}
elseif(frameSize.height>smallResource.size.height)
{
searchPath.push_back(mediumResource.directory);
pDirector->setContentScaleFactor(MIN(mediumResource.size.height/designResolutionSize.height,mediumResource.size.width/designResolutionSize.width));
}
else
{
searchPath.push_back(smallResource.directory);
pDirector->setContentScaleFactor(MIN(smallResource.size.height/designResolutionSize.height,smallResource.size.width/designResolutionSize.width));
}
CCFileUtils::sharedFileUtils()->setSearchPaths(searchPath);
pDirector->setDisplayStats(true);
pDirector->setAnimationInterval(1.0/60);
CCScene*pScene=HelloWorld::scene();
pDirector->runWithScene(pScene);
returntrue;
}
前面說過cocos2d-x2.2加入了很多新特性相關(guān)的代碼在helloworld例子里,這里面的一大段都是和屏幕自適應(yīng)相關(guān)的,因此可以跳過。
關(guān)鍵代碼為
開頭的
CCDirector*pDirector=CCDirector::sharedDirector();
CCDirector是游戲管理類,他的實(shí)例全局一份,通過CCDirector::sharedDirector()這個(gè)靜態(tài)函數(shù)取得,通過它可以取得一些游戲設(shè)置信息,也可以通過它控制當(dāng)前運(yùn)行哪個(gè)場(chǎng)景。
再看函數(shù)結(jié)尾部分
pDirector->setDisplayStats(true);
這句代碼設(shè)置在屏幕上顯示游戲運(yùn)行的幀數(shù),如果掉幀會(huì)立即看見
當(dāng)前幀數(shù)60幀,每次渲染次數(shù)為3
pDirector->setAnimationInterval(1.0/60);
這句設(shè)置游戲每幀間隔1/60秒
CCScene*pScene=HelloWorld::scene();
pDirector->runWithScene(pScene);
最后2句話是調(diào)用HelloWorld::scene函數(shù)創(chuàng)建一個(gè)ccscene,然后運(yùn)行這個(gè)場(chǎng)景(前面我說過的),之后scene里的精靈就會(huì)被繪制到屏幕上了。
第一次運(yùn)行場(chǎng)景調(diào)用runWithScene(pScene),如果是從一個(gè)場(chǎng)景切換到另一個(gè)場(chǎng)景則要調(diào)用replaceScene(pScene);
我們的ccscene是調(diào)用HelloWorld::scene這個(gè)靜態(tài)函數(shù)創(chuàng)建出來的,這個(gè)場(chǎng)景里有一張背景圖一個(gè)文字label以及一個(gè)按鈕
在看HelloWorldScene類之前,我們先普及另外的要點(diǎn)知識(shí)
要點(diǎn)2:
1.layer:在scene和sprite之間還有一個(gè)layer(層)的概念。一般來說,我們要?jiǎng)?chuàng)建一個(gè)或多個(gè)層,把層添加場(chǎng)景里,再把精靈放進(jìn)層里。有了用層管理精靈
的概念后,我們?cè)谧鲇螒虻臅r(shí)候就可以把一個(gè)場(chǎng)景分成很多層,譬如說地圖層和對(duì)象層,還可以有特效層(子彈層)和ui層。層和層之間可以設(shè)置遮擋關(guān)系
,先繪制哪一層后繪制哪一層,也可以通過設(shè)置某一層的顯示或不顯示來屏蔽掉一層。層和層之間也可以是包含關(guān)系(父子關(guān)系),譬如說一個(gè)地圖層,我們可
以分成四個(gè)小層,這四個(gè)小層分別被添加了春夏秋冬四種風(fēng)格的精靈構(gòu)成四種景色的地圖。然后根據(jù)需要只讓其中一層顯示,就實(shí)現(xiàn)了一個(gè)場(chǎng)景里季節(jié)變換的效果。
同時(shí)由于layer這個(gè)類繼承了cocos2d-x的觸摸接口類,我們可以實(shí)現(xiàn)某一層的手指觸摸行為。
2.node結(jié)構(gòu):CCNode(節(jié)點(diǎn))是cocos2d-x里的一個(gè)比較底層的基類,我們常用的CCScene,CCLayer,CCSprite類都繼承了CCNode。CCNode具有容器功能
(有個(gè)children成員,是個(gè)隊(duì)列),每個(gè)ccnode都可以包含別的CCNode,通過addchild(m_other_node)函數(shù)把別的節(jié)點(diǎn)加為自己的子節(jié)點(diǎn),這種關(guān)系成為父子關(guān)系。
上級(jí)的node稱為parent(父親),下級(jí)的node成為child。正是由于ccnode的這種節(jié)點(diǎn)特性,我們才可以把layer加入scene,把sprite加入layer。形成一個(gè)樹形結(jié)構(gòu)。
3.內(nèi)存管理(引用計(jì)數(shù)器和代碼風(fēng)格):這一段如看不懂,直接跳過。cocos2d-x的retain和release機(jī)制(引用計(jì)數(shù)器機(jī)制)引自objective-c。在java和c#這些語言里,當(dāng)一個(gè)對(duì)象不被任何人引用時(shí),所占
內(nèi)存會(huì)自動(dòng)釋放,在c++里程序員new出來的對(duì)象,需要自己delete。而在cocos2d-x(objective-c)里。我們創(chuàng)建出來的大多數(shù)對(duì)象都繼承CCObject這個(gè)類,它有一個(gè)計(jì)數(shù)器。一般來說
new出來的對(duì)象,計(jì)數(shù)器為1。如果我們對(duì)其使用retain,計(jì)數(shù)器就會(huì)加1.如果我們對(duì)其使用release,計(jì)數(shù)器就會(huì)-1,當(dāng)計(jì)數(shù)器為0時(shí),對(duì)象就會(huì)被析構(gòu)。和reatinrelease并行的還有一個(gè)auotorelease
的概念,如果我們將一個(gè)ccobject設(shè)為autorelease,它被被加到一個(gè)池里,當(dāng)它計(jì)數(shù)器為1時(shí)它也會(huì)在某個(gè)時(shí)間段被自動(dòng)釋放。那么如果我們得到一個(gè)ccobject,我們?cè)趺粗浪挠?jì)數(shù)器為幾,又是不是
auotorelease的呢?這里有個(gè)語法規(guī)范,只要不是通過new出來的對(duì)象,而是通過其他接口得到的(譬如helloworld::scene()),它就應(yīng)該是autorelease的,并且對(duì)我們來說它的計(jì)數(shù)器為1.應(yīng)為就算它
被外部retain過,它也必然會(huì)在某個(gè)時(shí)間被外部release(成對(duì)出現(xiàn),保證內(nèi)存不泄露),因此我們?nèi)绻挥羞€需要使用這個(gè)對(duì)象,并且不能保證在這之前,外部都不將其release,我們就應(yīng)該手動(dòng)將其retain
并且在不用的時(shí)候?qū)⑵鋜elease。譬如說CCDirector在切換到某個(gè)場(chǎng)景時(shí),就會(huì)將其retain,確保其不會(huì)被釋放,在下次切換時(shí),將其release,這樣就不會(huì)導(dǎo)致該場(chǎng)景永遠(yuǎn)不被釋放(release只是表示我們不需要
這個(gè)對(duì)象了,不代表此時(shí)該對(duì)象就會(huì)被釋放,因?yàn)閯e處可能對(duì)其retain了,還需要這個(gè)對(duì)象)。
基于這種前提,我們一般寫的類,都不會(huì)把構(gòu)造函數(shù)暴露,讓別處直接newClassX(),而是封裝一個(gè)靜態(tài)函數(shù)create()確保別人能得到一個(gè)auotorelease的對(duì)它來說計(jì)數(shù)器為1的實(shí)例對(duì)象。
在create函數(shù)里,我們new出一個(gè)對(duì)象,執(zhí)行初始化函數(shù)init(),并將其設(shè)為autorelease,將其返回。舊版本的cocos2d-x為了和cocos2d(objective-c版本)接口一致,采用的是類名()寫法。
例如CCNode::Node()這樣的寫法,已經(jīng)被新版拋棄,因?yàn)椴贿m合c++。
下面看HelloWorldScene代碼,先看頭文件
#ifndef__HELLOWORLD_SCENE_H__
#define__HELLOWORLD_SCENE_H__
#include"cocos2d.h"
classHelloWorld:publiccocos2d::CCLayer
{
public:
virtualboolinit();
staticcocos2d::CCScene*scene();
voidmenuCloseCallback(CCObject*pSender);
CREATE_FUNC(HelloWorld);
};
#endif//__HELLOWORLD_SCENE_H__
HelloWorld是一個(gè)繼承了CCLayer的類,里面有個(gè)init函數(shù)是初始化函數(shù),有個(gè)靜態(tài)函數(shù)scene會(huì)返回一個(gè)scene,這個(gè)scene里被添加了一個(gè)cclayer。
我們說了HelloWorldlayer里有一張北京,一個(gè)文字label,一個(gè)按鈕,menuCloseCallback就是點(diǎn)擊按鈕后的回調(diào)函數(shù)。
create函數(shù)跑哪去了?CREATE_FUNC(HelloWorld),這是一個(gè)宏,由于大多數(shù)的類都有create靜態(tài)函數(shù),內(nèi)容都是new一個(gè)對(duì)象指針,將其init(),設(shè)為auotorelease再返回,寫起來很煩
代碼也會(huì)變長(zhǎng),所以cocos2d-x給我們寫好了不少這樣的宏。翻譯過來就是
staticHelloWorld*create()
{
HelloWorld*pRet=newHelloWorld();
if(pRet&&pRet->init())
{
pRet->autorelease();
returnpRet;
}
else
{
deletepRet;
pRet=NULL;
returnNULL;
}
}
節(jié)省了不少行代碼,不過我一般懶得用宏,這么幾行代碼,其實(shí)順手就寫掉了。
由此可見,主要初始化內(nèi)容都是寫在init()函數(shù)里。那么去看cpp文件吧
#include"HelloWorldScene.h"
#include"AppMacros.h"
USING_NS_CC;
CCScene*HelloWorld::scene()
{
CCScene*scene=CCScene::create();
HelloWorld*layer=HelloWorld::create();
scene->addChild(layer);
returnscene;
}
boolHelloWorld::init()
{
if(!CCLayer::init())
{
returnfalse;
}
CCSizevisibleSize=CCDirector::sharedDirector()->getVisibleSize();
CCPointorigin=CCDirector::sharedDirector()->getVisibleOrigin();
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));
CCMenu*pMenu=CCMenu::create(pCloseItem,NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu,1);
CCLabelTTF*pLabel=CCLabelTTF::create("HelloWorld","Arial",TITLE_FONT_SIZE);
pLabel->setPosition(ccp(origin.x+visibleSize.width/2,
origin.y+visibleSize.height-pLabel->getContentSize().height));
this->addChild(pLabel,1);
CCSprite*pSprite=CCSprite::create("HelloWorld.png");
pSprite->setPosition(ccp(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));
this->addChild(pSprite,0);
returntrue;
}
voidHelloWorld::menuCloseCallback(CCObject*pSender)
{
#if(CC_TARGET_PLATFORM==CC_PLATFORM_WINRT)||(CC_TARGET_PLATFORM==CC_PLATFORM_WP8)
CCMessageBox("Youpressedtheclosebutton.WindowsStoreAppsdonotimplementaclosebutton.","Alert");
#else
CCDirector::sharedDirector()->end();
#if(CC_TARGET_PLATFORM==CC_PLATFORM_IOS)
exit(0);
#endif
#endif
}
靜態(tài)函數(shù)scene()返回一個(gè)scene,里面包含了一個(gè)HelloWorld(這是一個(gè)層)。
在創(chuàng)建HelloWorld時(shí),是調(diào)用create函數(shù)得到的,create()函數(shù)調(diào)用了init()函數(shù),下面看init()函數(shù)
首先執(zhí)行父類的初始化函數(shù),然后拿到屏幕大小
CCSizevisibleSize=CCDirector::sharedDirector()->getVisibleSize();
CCPointorigin=CCDirector::sharedDirector()->getVisibleOrigin();
舊版本的例子是直接拿的getwinSize()。這里說明一下,2.2版本給大家展示了屏幕自適應(yīng),也就是我們之前在appdelegate里沒有說明的那一段,由于設(shè)置了屏幕自適應(yīng)的關(guān)系,
雖然我們?cè)趍ain函數(shù)里設(shè)置了視圖大小,但是并不是說整個(gè)視圖都能繪制到屏幕上,可能只有中間部分繪制出來,多出去的部分就看不到了,getVisibleSize()函數(shù)就是拿到可繪制
出的部分的大小,getVisibleOrigin()則是可繪制部分左下角點(diǎn)相對(duì)于視圖左下角點(diǎn)的坐標(biāo)(關(guān)于自適應(yīng)我之后的博文會(huì)仔細(xì)說)。
hellowWorld的例子是將視圖等比放大到無黑邊,這樣就可能導(dǎo)致上下抑或左右有部分顯示不出來,而拿到可顯示部分的起始坐標(biāo)和長(zhǎng)寬就可以把精靈定位到屏幕的
左下(origin.x,origin.x+visibleSize.height/2),
右下(origin.x+visibleSize.width,origin.x+visibleSize.height/2),
抑或是中間(origin.x+visibleSize.width/2,origin.x+visibleSize.height/2)
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));
CCMenu*pMenu=CCMenu::create(pCloseItem,NULL);
pMenu->setPosition(CCPointZero);
this->addChild(pMenu,1);
CCMenuItemImage這個(gè)類菜單原件的一種(是個(gè)由2張圖片精靈組成的按鈕),它的create函數(shù)有四個(gè)參數(shù),前個(gè)參數(shù)是圖片名,分別是點(diǎn)擊前要顯示的圖片,可以點(diǎn)擊時(shí)
顯示的圖片。之后的2個(gè)參數(shù)分別是點(diǎn)擊后要執(zhí)行回調(diào)的對(duì)象和回調(diào)函數(shù)的指針,menu_selector(HelloWorld::menuCloseCallback)這種寫法是模仿objective-c里的selector,
menu_selector是個(gè)宏,內(nèi)容其實(shí)就是把函數(shù)指針強(qiáng)轉(zhuǎn)為CCObject的函數(shù)指針,如果看不懂也沒關(guān)系,照著寫就行了。
pCloseItem->setPosition(ccp(origin.x+visibleSize.width-pCloseItem->getContentSize().width/2,origin.y+pCloseItem->getContentSize().height/2));
setPosition(x,y)函數(shù)是設(shè)置Node的坐標(biāo)
而getContentSize()會(huì)返回Node的大小
這里把pCloseItem放在了屏幕右下角
但是由于CCMenuItemImage沒有實(shí)現(xiàn)cocos2d-x觸摸接口,因此要把它塞進(jìn)一個(gè)CCMenu里,才能點(diǎn)擊。
CCMenu是菜單容器類,在cocos2d-x2.2里它繼承了layer(之前說過layer繼承了觸摸接口),因此具有觸摸行為,相當(dāng)于一個(gè)菜單層。把菜單原件塞進(jìn)CCMenu里,再把CCMenu
塞進(jìn)layer里,就可以看到按鈕并且可以點(diǎn)擊了。
pMenu->setPosition(CCPointZero);
this->addChild(pMenu,1);
pMenu的坐標(biāo)相對(duì)于layer是左下角點(diǎn)(0,0),而按鈕相對(duì)于pMenu相對(duì)于pMenu是屏幕右下的位置,因此pMenu相對(duì)于layer也是屏幕右下的位置。
注意,this->addChild(pMenu,1);這里addchild函數(shù)里多傳了一個(gè)數(shù)字,這個(gè)參數(shù)是Z值。一個(gè)layer里有很多精力,繪制時(shí)的遮擋關(guān)系是怎樣的呢。答案是Z值大的會(huì)確保被繪制在
z值小的上面。這里傳的給pMenu傳的Z值是1,之后比1小的都會(huì)在pMenu下面。如果沒傳Z值,默認(rèn)是0。
menuCloseCallback是點(diǎn)擊按鈕的回調(diào)函數(shù),里面根據(jù)CC_TARGET_PLATFORM預(yù)定義宏的值得不同,寫了不同的處理代碼。
CC_TARGET_PLATFORM宏是平臺(tái)標(biāo)示宏,因?yàn)槲覀兊钠脚_(tái)是win32,因此,我們會(huì)被編譯的代碼只是一句
CCDirector::sharedDirector()->end();這句函數(shù)的意思是關(guān)閉程序。
CCSprite是一個(gè)關(guān)聯(lián)圖片的類,當(dāng)我們想添加一個(gè)圖片對(duì)象時(shí),就會(huì)創(chuàng)建CCSprite,那么對(duì)于文字我們使用CCLabelTTF類。
CCLabelTTF*pLabel=CCLabelTTF::create("HelloWorld","Arial",TITLE_FONT_SIZE);
pLabel->setPosition(ccp(origin.x+visibleSize.width/2,origin.y+visibleSize.height-pLabel->getContentSize().height));
this->addChild(pLabel,1);
CCLabelTTF類的創(chuàng)建函數(shù)傳入三個(gè)參數(shù),分別是文字內(nèi)容,字體,和大小。
創(chuàng)建出來的pLabel在屏幕中間偏上部分。
設(shè)置的Z值也為1,但是由于是后添加的,所以在菜單層之上。
CCSprite*pSprite=CCSprite::create("HelloWorld.png");
pSprite->setPosition(ccp(visibleSize.width/2+origin.x,visibleSize.height/2+origin.y));
this->addChild(pSprite,0);
最后,我們創(chuàng)建一個(gè)背景,并添加到場(chǎng)景里。
CCSprite的創(chuàng)建函數(shù)只要傳入一個(gè)圖片名即可(事實(shí)上,其實(shí)上有三個(gè)重載,但是暫時(shí)用不到)。
圖片被放在屏幕正中央,有傳入的Z值為0,所以會(huì)被繪制在最下面。
關(guān)于HelloWorld代碼本身的解析就到此為止。
ps:注意我們創(chuàng)建的CCSprite由于是create接口得到到,并不是直接new出來的,那么我們應(yīng)該把它看做(事實(shí)上也是)計(jì)數(shù)器為1且autorelease,那么它不會(huì)被銷毀么。
事實(shí)上,由于它被加入到了layer里,而CCNode在添加一個(gè)child時(shí)會(huì)自動(dòng)把child的計(jì)數(shù)器加1,移除時(shí)-1.因此不需要我們手動(dòng)retain了。等切換場(chǎng)景導(dǎo)致當(dāng)前場(chǎng)景銷毀時(shí),所有
子節(jié)點(diǎn)會(huì)被移除,子節(jié)點(diǎn)也會(huì)被銷毀。
或許有許多朋友會(huì)說我這篇博文說的比較粗糙,許多相關(guān)點(diǎn)沒有詳細(xì)說。這里我要說明一下,我不打算像翻譯工一樣把每一句代碼的意思給翻譯一遍,這篇博文的
目的只是帶朋友們熟悉一下cocos2d-x引擎的代碼風(fēng)格和框架,因此我對(duì)計(jì)數(shù)器以及node結(jié)構(gòu)反而多說了幾句。helloworld是比較簡(jiǎn)單的例子,但是在cocos2d-x2.2的版本里,由于開發(fā)人員想展示許多新特性,新的函數(shù)接口,加了許多相對(duì)新手來說比較難以理解的代碼,加大了閱讀難度,不適合在一開始就拿來說。既然寫教程,就要能夠幫助新人迅速上手,減少難度,一點(diǎn)一點(diǎn)把知識(shí)點(diǎn)傳輸給讀者。看了這篇文章的讀者如果知道了如何創(chuàng)建一個(gè)scene以及創(chuàng)建一個(gè)精靈,繪制到屏幕上,就算過關(guān)了。
之后博客會(huì)有2個(gè)分支
1:我一直堅(jiān)信程序員只要能貼圖就能做游戲,之后我會(huì)寫幾個(gè)簡(jiǎn)單的游戲例子,由簡(jiǎn)到難分好幾步。最初的代碼甚至不考慮屏幕分辨率也不適用動(dòng)畫,然后慢慢實(shí)現(xiàn)這些功能,每次加入幾個(gè)cocos2d-x常用類抑或是機(jī)制的適用和說明。最初可能是簡(jiǎn)單的打氣球之類的小游戲,最后是塔防抑或是rpg這種稍微大點(diǎn)的項(xiàng)目。跟著這條線走的朋友會(huì)學(xué)的比較輕松,唯一的敵人可能就是我博客的更新速度。
2:cocos2d-x自帶的testcpp的例子其實(shí)很經(jīng)典,許多朋友卻懶得看,我打算一一進(jìn)行講解,到時(shí)候我的博客就有類似工具書的作用了。已經(jīng)入門的朋友到時(shí)可以跟這條線。不過我不知道說明時(shí)候能更新就是了。
大家在學(xué)習(xí)cocos2d-x的時(shí)候一定要按著引擎的框架走,按cocos2d-x的風(fēng)格寫代碼,嚴(yán)格遵守retainrelease機(jī)制,就不會(huì)出現(xiàn)代碼莫名其妙編譯不過去的情況了。最后祝大家晚安,下一篇博文開始要實(shí)際做游戲了,養(yǎng)好精神吧。
轉(zhuǎn)載于:https://www.cnblogs.com/MiniHouse/p/3960062.html
總結(jié)
以上是生活随笔為你收集整理的helloworld讲解cocos2d-x的编程思路与要点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: JavaScript对象的创建之构造函数
- 下一篇: 泛型Dictionary的用法详解
