cocos2d基础介绍
這篇文章主要會介紹一些cocos2d的基礎(chǔ)類,以及他們的用途。
?
cocos2d中,大量使用了單例(singleton)模式,單例其實(shí)就是一個普通的類,但是它在整個應(yīng)用程序生命周期內(nèi)只實(shí)例化一次,cocos2d中,要訪問單例對象,基本上都是使用shared開頭的方法(目前為止,我沒有發(fā)現(xiàn)過有不這樣使用的單例)。如果你還沒看懂單例是什么,那么看看下面這個例子你就知道了。
static MyManager *shareManager = nil;+(MyManager) sharedManager
{
if(shareManager == nil)
{
shareManager = [[MyManager alloc] init];
}
return shareManager;
}
我覺得單例應(yīng)該是包含了一些公用的方法,而且調(diào)用這些方法,不會去修改單例的屬性,否則其他的類來調(diào)用單例的時候,所遇到的結(jié)果就是未知的了。說完單例,我們先來說說一個重要的單例類——CCDirector。CCDiretor類是Cococs2d游戲引擎的核心,它存儲了cocos2d種大量的全局配置信息,而且管理著所有的cocos2d場景。Dirctor的主要作用有一下幾點(diǎn):
- 切換場景
- 存儲cocos2d的配置信息
- 訪問試圖(包含OpenGL、UIView、UIWindow)
- 暫停、恢復(fù)以及終止游戲
- 在UIKit和OpenGL之間轉(zhuǎn)換坐標(biāo)
- CCNode類
? ? ?接下來,說說CCNode類。cocos2d中,所有的節(jié)點(diǎn)都繼承自CNode類,它是一個沒有具體顯示的抽象類,僅用于定義所有的公共屬性和方法。首先我們來看一下cocos文檔里面列舉出來的類的繼承關(guān)系,可以從中發(fā)現(xiàn)CCScene、CCSprite都繼承自CCNode,以前CCLayer也應(yīng)該是繼承自CCNode,但是在1.0.1的文檔中查不到這個類,先記錄下,等下再去查。
?
再來看看這個類的部分公共函數(shù),里面包含了各種對節(jié)點(diǎn)的操作,增加、刪除、獲取節(jié)點(diǎn)、調(diào)度(即隔多少秒執(zhí)行一次,稍后會詳細(xì)說、取消調(diào)度、開始播放動作、停止動作等):
| (void)? | -?addChild: |
| (void)? | -?addChild:z: |
| (void)? | -?addChild:z:tag: |
| (void)? | -?removeFromParentAndCleanup: |
| (void)? | -?removeChild:cleanup: |
| (void)? | -?removeChildByTag:cleanup: |
| (void)? | -?removeAllChildrenWithCleanup: |
| (CCNode?*)? | -?getChildByTag: |
| (void)? | -?reorderChild:z: |
| (void)? | -?cleanup |
| (void)? | -?draw |
| (void)? | -?visit |
| (void)? | -?transform |
| (void)? | -?transformAncestors |
| (CGRect)? | -?boundingBox |
| (CGRect)? | -?boundingBoxInPixels |
| (CCAction?*)? | -?runAction: |
| (void)? | -?stopAllActions |
| (void)? | -?stopAction: |
| (void)? | -?stopActionByTag: |
| (CCAction?*)? | -?getActionByTag: |
| (NSUInteger)? | -?numberOfRunningActions |
| (void)? | -?scheduleUpdate |
| (void)? | -?scheduleUpdateWithPriority: |
| (void)? | -?schedule: |
| (void)? | -?schedule:interval: |
| (void)? | -?unschedule: |
| (void)? | -?unscheduleAllSelectors |
| (void)? | -?resumeSchedulerAndActions |
| (void)? | -?pauseSchedulerAndActions |
?
- CCScene類
? ? ?一個CCScene對象往往是場景圖種的第一個節(jié)點(diǎn)。通常來說,CCScene節(jié)點(diǎn)的第一層子節(jié)點(diǎn)一定是CCLayer的子類,而CCScene對象本身,通常是利用CCLayer對象種的靜態(tài)方法+(id)scene來創(chuàng)建,而且游戲中的各個對象,也通常是由這些子節(jié)點(diǎn)(CCLayer)來保存,而不是CCScene本身來保存,這樣做的好處,會在CCLayer部分介紹。
?
? ? ?1、場景類跟app建立關(guān)系上
? ? ?我們可以把要顯示的第一個場景,加在AppDelegate中applicationDidFinishLaunching方法的最后,類似如下:
? ? ?[[CCDirector sharedDirector] runWithScene:[HelloWorld scene]];
?
? ? ?HelloWold類是一個繼承自CCLayer的類,scene是其中的一個靜態(tài)方法,用來將layer加入scene里面,如下所示:
+(id)scene{
CCScene *scene = [CCScene node];
CCLayer *layer = [HelloWord node];
[scene addChild:layer];
return scene;
}
?
? ? ?2、內(nèi)存使用
? ? ?當(dāng)進(jìn)行場景替換的時候,cocos2d會把自己占用的內(nèi)存清理干凈,它會刪除所有的節(jié)點(diǎn),停止所有的動作,并且對所有用選擇器選中的方法取消調(diào)度。但是,由于在進(jìn)行場景替換時,新場景往往在舊場景釋放之前就被加載到內(nèi)存了,這會導(dǎo)致內(nèi)存負(fù)荷瞬間加大,這個問題在使用場景轉(zhuǎn)換動畫的時候,顯得格外明顯。這時候,場景首先會被創(chuàng)建,然后過渡效果運(yùn)行,一直要到過度效果運(yùn)行完畢之后,舊場景才會從內(nèi)存中釋放。
由于場景替換的時候,會停止所有的動作,那么可否在播放場景過渡動畫前先把前一個場景截屏,然后釋放掉前一個場景再播放動畫,這樣的話,就能節(jié)省不少內(nèi)存。
?
? ? ?3、場景的推進(jìn)和彈出
? ? ?cocos2d種有pushScene和popScene這兩個有用的方法,這兩個方法用來在不釋放舊場景內(nèi)存的情況下運(yùn)行新場景,可以加快場景替換的速度。由于很多場景可以互相疊加的存在于內(nèi)存之中,很容易就會忘記彈出一個場景,或者對于同一個場景彈出太多遍。學(xué)過堆棧的同學(xué),應(yīng)該知道這種情況的危險性。但是這個用來切換setting還是不錯的選擇,因?yàn)閟etting一般都不怎么占內(nèi)存,當(dāng)然,特殊情況除外。
?
- CCTransitonScene
? ? ?場景過渡動畫有時候能為游戲添色不少。在cocos2d中,要使用過度動畫還是比較簡單的,只要在場景轉(zhuǎn)換時添加兩行代碼就行了。比如下面這個淡入淡出效果:
? ??
CCFadeTransition *tran = [CCFadeTransition transitionWithDuration:1scene:[HelloWorld scene]
withColor:ccWHITE];
[[CCDirector sharedDirector] replaceScene:tran];
?
?
? ? ?CCTransitonScene定義了很多的場景轉(zhuǎn)換動畫,看下下面這張類圖應(yīng)該能很清楚的知道:
?
- CCLayer
? ? ?開始在CCScene里面提到過,CCLayer本質(zhì)是對節(jié)點(diǎn)進(jìn)行分組,游戲中的各個對象,一般是用CCLayer來保存的。這樣的好處是,可以很輕松的修改層的屬性或者在該層上運(yùn)行一個動作來影響層上的所有子節(jié)點(diǎn)。例如你可以對某一層施加一個動作,然后這個動作會對該層上的所有對象產(chǎn)生影響。當(dāng)然,不使用層也能達(dá)到這樣的效果,只要對每個對象分別進(jìn)行操作即可,但是顯然,不使用層的做法是非常低效的。
?
? ? ?CCLayer能夠接收觸摸事件和加速劑事件,但是接收觸摸或者加速計事件的開銷是很大的,這也就導(dǎo)致有人說使用多個層會影響性能。實(shí)際上你可以使用任意多個蹭,與其他的節(jié)點(diǎn)相比,他們對于性能并沒有太大的影響。如果太多的層需要接收和處理觸摸或者加速計事件,可以只用一個蹭來接收和處理這些輸入,然后在必要的情況下,通過這個層將輸入事件通知給其他節(jié)點(diǎn)或者類。
?
? ? ?1、接收觸摸事件
? ? ?使用self.isTouchEnabled = YES來顯示啟動接收觸摸事件,一般會在init方法中開啟此功能。下面列出幾個常用單點(diǎn)觸控的觸摸事件:
? ? ?a)當(dāng)手指接觸到屏幕時被調(diào)用:
-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event?
? b)當(dāng)手指離開屏幕時候被調(diào)用:
-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event?? ? ?c)當(dāng)觸摸時間被取消時調(diào)用:
-(void) ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event? ? ?d)當(dāng)手指在屏幕上移動的時候被調(diào)用:
? ??
-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event? ? ?在使用單點(diǎn)觸摸之前,要向?qū)又刑砑右韵路椒▉韱⒂糜嗅槍π缘挠|摸處理:
-(void) registerWithTouchDispatcher{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
priority:INIT_MIN + 1
swallowsTouches:YES];
}?
? ? ?CCTouchBegan返回一個bool值,如果返回YES,就意味著不想讓這個觸摸被傳送到其他優(yōu)先級更低的有針對性的觸摸處理,也就相當(dāng)于你直接吞噬掉了這個觸摸事件。
?
? ? ?由于觸摸事件是由Cocoa Touch API接收的,因此一定要吧觸摸位置轉(zhuǎn)換成cocos2d所用的OpenGL坐標(biāo):
? ? ?
-(CGPoint) locationFromTouch:(UITouch *)touch{
CGPoint touchLocation = [touch locationInView:[touch view]];
return [[CCDirector sharedDirector] convertToGL:touchLocation];
}
? ? ?2、接收加速計事件
? ? ?同樣,需要self.isAccelerometerEnabled = YES來顯示啟動加速計來接收加速計事件,但是這個事件的處理比觸摸時間就簡單多了,只需要向?qū)永锩嫣砑右粋€特定方法來接收加速計事件:
? ? ?
- (void)accelerometer:(UIAccelerometer*)accelerometerdidAccelerate:(UIAcceleration*)acceleration
{
//可以利用以下參數(shù)來決定三維中任意方向的加速度
//acceleration.x acceleration.y acceleration.z
}
?
- CCSprite
?
?
? ? ?CCSprite是cocos2d種最為常用的類,它用一副圖像將精靈顯示到屏幕上。要創(chuàng)建一個精靈很簡單,比如你的工程的Resources分組下有一張叫做monster.png的圖,那么只需要使用如下方法,就能將精靈顯示在層上:
CCSpirt *sprite = [[CCSprite spriteWithFile:@"monster.png"]];[self addChild:sprite];? ?
? ? ?通過上面的操作后,cocos2d內(nèi)部會把該圖片加載到CCTexture2D類的圖像資源中。在這里,順便提一下,由于ios設(shè)備只支持尺寸為“2的n次冪”的紋理,即圖片的長寬只能偉:2、4、8等像素。如果你有一張貼圖,大小為260*260像素32位色的圖片,那么就比較悲劇了。你覺得它在內(nèi)存中應(yīng)該只占用260*260*4=270KB左右的空間,單實(shí)際上,它占用了512*512*4=1MB的內(nèi)存。
? ? ? CCSprite還有一個比較重要的就是位置問題,想象下現(xiàn)實(shí)生活中,如果你要把一張照片釘在墻上某個問題,你會怎么做?首先,你會把圖釘插在照片上的某個點(diǎn)(在cocos2d中稱為anchorPoint),然后你會確定要把這個圖釘訂在墻上的某個位置(在cocos2d種稱為positon),這兩個點(diǎn)就能確定照片在墻上的位置了。比如你想把照片放到左下角,那么你可以選擇將圖釘釘在照片的左下角(0,0),然后釘在墻的左下角(0,0).或者,你可以選擇把圖釘定在照片的右上角(1,1),然后把照片訂在墻的(照片長,照片寬)的位置。auchorPoint表示的其實(shí)是一個百分比,用來標(biāo)明相對于圖片左下角的(長*百分比,寬*百分比)像素的位置,比如auchorPoint為(0.5, 0.5), 那么在圖片的坐標(biāo)系里,它標(biāo)明的位置就應(yīng)該是(長*0.5, 寬*0.5)的位置,也就是圖片的中心點(diǎn)。最好好anchorPoint設(shè)置成(0.5, 0.5),也就是在圖片的中心,這樣,當(dāng)你進(jìn)行旋轉(zhuǎn)、縮放等動作的時候,會比較方便。幸運(yùn)的是,anchorPoint的默認(rèn)位置就是(0.5,0.5).
- CCLabelTTF
? ? ?這個類的作用就是在屏幕上顯示文本。cocos2d內(nèi)部會以制定的字體作為參數(shù)創(chuàng)建一個CCTexture2D對象,也就是一張紋理,然后再用改紋理渲染出最后顯示的文本.因?yàn)槊看挝谋景l(fā)生改變,就要做一次上述工作,所以cocos2d的文檔中也建議改用CCLabelAtlas或者CCLabelBMFont代替。
? ? ?你可能會發(fā)現(xiàn),每次修改標(biāo)簽上的文本時候,這些文本都會自動中對齊,如果要改成左對齊,或者右對齊這些,只需要改變anchorPoint的屬性就可以了。
- 動作
? ? ?動作是可以用來讓節(jié)點(diǎn)執(zhí)行諸如移動、旋轉(zhuǎn)、縮放、變色、消失等很多動作。由于他們能作用在所有的節(jié)點(diǎn)上,因此可以對精靈、標(biāo)簽甚至菜單或整個場景施加動作。動作在完成后,會自動從節(jié)點(diǎn)上清除并釋放它所占用的內(nèi)存。
? ? ?動作又分為即時動作和延時動作。延時動作就是我們一般理解上的動作,比如讓一個精靈移動到哪里。即時動作,一般就類似于設(shè)置精靈的屬性等,及時動作平時看起來是沒有多大意義的,一般要配合后文所述的動作序列。
? ? ?1)重復(fù)動作
? ? ?這個很容易理解,就是讓一個動作不停的重復(fù),可以用這個方法創(chuàng)建無限循環(huán)的動畫。使用起來也很簡單,例如下面這個讓一個節(jié)點(diǎn)不停的旋轉(zhuǎn):
? ? ?
CCRotateBy* rotateBy = [CCRotateBy actionWithDuration:2 angle:360];CCRepeatForever *repeat = [CCRepeatForever actionWithAction:rotateBy];
[myNode runAction:repeat];?
? ? ?還有一個類CCRepeat是讓一個動畫重復(fù)多少次,函數(shù)原型如下:? ? ?
actionWithAction:(CCFiniteTimeAction *)action times:(NSUInteger) times;
? ? ?2、流暢動作(CCEaseAction)?
? ? ?一般的動作,比如你定義了一個物體是向哪個方向移動,那么它就會勻速的過去,但是很顯然,我們喜歡更有點(diǎn)變化的動作,比如加速進(jìn)入,然后迅速一段時間,再減速停止,流暢動作就是用來做這個的。
?
? ? ?3、動作序列
? ? CCSequence,這個比較好理解,就是定義一組動作,然后讓他們按照這個順序執(zhí)行。
?
? ? ?上面介紹了cocos2d種一些重要的、常用的類,接下來的文章,會采用這些來做一個小demo,來溫習(xí)一下這一篇文章的內(nèi)容,不正確的地方,還請各位斧正。?
轉(zhuǎn)載于:https://www.cnblogs.com/huangwei/archive/2012/03/16/2402322.html
總結(jié)
以上是生活随笔為你收集整理的cocos2d基础介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 自然归并排序 c++ (原创)
- 下一篇: 1027. Colors in Mars