使用C++進(jìn)行Cocos2d-x游戲開發(fā)入門過(guò)程中的要點(diǎn)解析
總結(jié)了下,新手引導(dǎo)的要點(diǎn)有以下幾個(gè):
- 畫面的變化.
- 觸摸和按鈕響應(yīng).
- 邏輯處理及代碼組織.
下面我們就詳細(xì)講述這幾個(gè)要點(diǎn):
一.畫面的變化.
對(duì)個(gè)這個(gè)不同的游戲的做法不盡相同,歸結(jié)起來(lái)大概有這么幾種:
1.畫面整體變暗
這個(gè)比較簡(jiǎn)單,cocos2d就有現(xiàn)成接口:
CCSize visibleSize = CCDirector::sharedDirector()->getVisibleSize(); //第一個(gè)參數(shù)是顏色ccc4(r,g,b,a) a取值(0~255),越大越不透明 下面兩個(gè)參數(shù)為寬高,不傳默認(rèn)為屏幕大小 CCLayerColor* pLayer=CCLayerColor::create(ccc4(0,0,0,200),visibleSize.width,visibleSize.height); //CCLayerColor* pLayer=CCLayerColor::create(ccc4(0,0,0,200)); addChild(pLayer,100);
效果如下:
然后你可以在這層之上添加精靈,最后的效果可能是這個(gè)樣子的:
注:圖片源自網(wǎng)絡(luò),如果有版權(quán)問題~你丫去死吧! 請(qǐng)聯(lián)系我!
2.局部高亮
比較簡(jiǎn)單的方法是準(zhǔn)備幾張張局部高亮的圖片,隨著引導(dǎo)進(jìn)度變化而切換!優(yōu)點(diǎn)是可以做的比較精美,缺點(diǎn)是資源量會(huì)比較大!另一種方法是在畫面整體變暗的基礎(chǔ)上摳掉部分區(qū)域,還好cocos2d提供了CCClippingNode接口(2.1+版)!
CCClippingNode類比較復(fù)雜,但我們只用明白兩個(gè)東西就好:一個(gè)是CCClippingNode的Stencil,一個(gè)CCClippingNode的Child,怎么理解呢?請(qǐng)看下圖:
這個(gè)東西相信大家都有印象吧,上面的圖案(鏤空部分)就是 CCClippingNode的Stencil(模板),實(shí)體部分就是CCClippingNode的child(底板),是不是很好明白,讓我們用代碼來(lái)實(shí)現(xiàn)吧:
//創(chuàng)建cliper對(duì)象 CCClippingNode* pClip=CCClippingNode::create(); addChild(pClip); //加入灰色的底板 CCLayerColor* pColor=CCLayerColor::create(ccc4(0,0,0,200)); pClip->addChild(pColor);
讓我來(lái)加入模板:
//創(chuàng)建drawnode對(duì)象 CCDrawNode *m_pAA=CCDrawNode::create(); static ccColor4F green = {0, 1, 0, 1}; static CCPoint rect[4]={ccp(-50,50),ccp(50,50),ccp(50,-50),ccp(-50,-50)}; //用上面的數(shù)據(jù)保存一個(gè)100x100的矩形 m_pAA->drawPolygon(rect, 4, green, 0, green); //設(shè)置到屏幕的中心 m_pAA->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); //設(shè)置為pclip的模板 pClip->setStencil(m_pAA);
CCDrawNode是用來(lái)繪制幾何圖形的,drawPolygon使用繪制多邊形,參數(shù)為頂點(diǎn)數(shù)組,頂點(diǎn)數(shù)量,邊框?qū)挾?和填充顏色!這里要注意一點(diǎn):千萬(wàn)不要addChild(m_pAA);因?yàn)橐坏゛ddchild,m_pAA就會(huì)被繪制出來(lái),我們是要用它做剪裁!他會(huì)在CCClippingNode內(nèi)部被使用!
我們會(huì)看到這樣的效果:
額,貌似和我們想想的不太一樣啊,為什么呢?那是因?yàn)镃CClippingNode有一個(gè)選項(xiàng)是是否反向,既顯示Stencil呢還是child減去Stencil的部分!默認(rèn)為顯示顯示鏤空(Stencil)部分(false),因此我們要改變選項(xiàng):
//是否反向? pClip->setInverted(true);
效果如下,是不是很棒:
3.組合效果(將2的矩形改成圓,再加上圖片)
讓我們先看這張圖片,是不是很棒?右下角黃色矩形區(qū)域是高亮的,在配上圖片說(shuō)明,很不錯(cuò)的效果!
讓我們來(lái)實(shí)現(xiàn)類似的效果吧,用到的資源:
//創(chuàng)建cliper CCClippingNode* pClip=CCClippingNode::create(); pClip->setInverted(true); addChild(pClip); //添加底板 CCLayerColor* pColor=CCLayerColor::create(ccc4(0,0,0,200)); pClip->addChild(pColor); //繪制圓形區(qū)域 static ccColor4F green = {0, 1, 0, 1};//頂點(diǎn)顏色,這里我們沒有實(shí)質(zhì)上沒有繪制,所以看不出顏色 float fRadius=55.0f;//圓的半徑 const int nCount=100;//圓形其實(shí)可以看做正多邊形,我們這里用正100邊型來(lái)模擬園 const float coef = 2.0f * (float)M_PI/nCount;//計(jì)算每?jī)蓚€(gè)相鄰頂點(diǎn)與中心的夾角 static CCPoint circle[nCount];//頂點(diǎn)數(shù)組 for(unsigned int i = 0;i <nCount; i++) { float rads = i*coef;//弧度 circle[i].x = fRadius * cosf(rads);//對(duì)應(yīng)頂點(diǎn)的x circle[i].y = fRadius * sinf(rads);//對(duì)應(yīng)頂點(diǎn)的y } CCDrawNode *pStencil=CCDrawNode::create(); pStencil->drawPolygon(circle, nCount, green, 0, green);//繪制這個(gè)多邊形! //動(dòng)起來(lái) pStencil->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f), CCScaleTo::create(0.125f, 1)))); pStencil->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); //設(shè)這模板 pClip->setStencil(pStencil); //添加圓和手的圖片 CCSprite*pCircle=CCSprite::create("circle.png"); pCircle->setPosition(ccp(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y)); pCircle->runAction(CCRepeatForever::create(CCSequence::createWithTwoActions(CCScaleBy::create(0.05f, 0.95f), CCScaleTo::create(0.125f, 1)))); addChild(pCircle); CCSprite* pHand=CCSprite::create("hand.png"); pHand->setAnchorPoint(ccp(0.0f,1.0f)); pHand->setPosition(ccp(pCircle->getContentSize().width/2,pCircle->getContentSize().height/2)); pCircle->addChild(pHand);
上面是全部的代碼,效果圖如下(動(dòng)態(tài)的會(huì)更好)沒有加圓圈和手之前和之后:
那么如何改變高亮區(qū)域得位置呢?很簡(jiǎn)單,只用改變pStencil的位置即可!可以考慮記為成員變量在ccTouchesBegan中改變位置,這樣就會(huì)高亮區(qū)域就會(huì)跟著你的鼠標(biāo)走啦!
二.觸摸和按鈕響應(yīng)
1.開啟觸摸 阻止穿透響應(yīng) 判斷落點(diǎn)
讓我們繼續(xù)看下面的這張圖片:
這張圖片中應(yīng)該只有右下角的”冒險(xiǎn)”按鈕能夠響應(yīng)的到,在這里說(shuō)下思路:
為了讓其他區(qū)域的按鈕響應(yīng)不到,我們應(yīng)該提高上層(CClayer)的響應(yīng)優(yōu)先級(jí)為-128和按鈕一樣,這樣的話如果上層(CClayer)后加入游戲addchild的話,會(huì)先收到觸摸消息.
在收到觸摸消息ccTouchBegan時(shí),判斷點(diǎn)擊的地方是否在黃色矩形區(qū)域中,在的話return false 交給下層的按鈕去響應(yīng),否則return true 阻止消息繼續(xù)傳遞.
下面是代碼片段:
1).開啟觸摸
bool CTeachLayer::init() { if (!CCLayer::init()) { return false; } setTouchEnabled(true); return true; }
2).提升觸摸響應(yīng)優(yōu)先級(jí)為-128
void CTeachLayer::registerWithTouchDispatcher() { //使用-128和CCMenu優(yōu)先級(jí)相同,并且吞掉事件true// CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, -128, true); CCLayer::registerWithTouchDispatcher(); }
3).在ccTouchBegan判斷觸點(diǎn)
bool CTeachLayer::ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent ) { //得到觸摸位置 CCPoint touchPoint = pTouch->getLocation(); //聲明一個(gè)右下角100x50的矩形 CCRect m_obRect=CCRectMake( CCDirector::sharedDirector()->getVisibleSize().width-100, CCDirector::sharedDirector()->getVisibleSize().height-50, 100, 50); //判斷點(diǎn)是否在矩形中 if (m_obRect.containsPoint(touchPoint)) { return false; } return true; }
大功告成,快去試一下吧!
2.精確命中
手機(jī)上和電腦上的觸摸事件的區(qū)別在于:電腦上我們是用鼠標(biāo)點(diǎn)擊,而手機(jī)上使用手指去摁,觸摸的精度的高低不言而喻!讓我們來(lái)看下面這張圖片:
讓我們看右上角的X號(hào)按鈕,在手機(jī)上點(diǎn)擊它來(lái)說(shuō)應(yīng)該是很困難的!他的真實(shí)尺寸應(yīng)該是紅色矩形的區(qū)域(假設(shè):50x50),為了讓玩家在引導(dǎo)時(shí),能夠很方便的點(diǎn)擊到它,我們將實(shí)際的可觸摸區(qū)域設(shè)置為藍(lán)色區(qū)域(假設(shè):100x100),這樣應(yīng)該很好點(diǎn)到了吧!
這樣會(huì)有一個(gè)新的問題,如果點(diǎn)擊到紅色和藍(lán)色之間的區(qū)域,下面的x按鈕時(shí)響應(yīng)不到的,那么怎么辦呢?我們需要修改touch的數(shù)據(jù)(設(shè)置為按鈕的正中心),然后touch事件將會(huì)以新的數(shù)據(jù)向下傳遞!這樣下面的按鈕就能響應(yīng)到了!
讓我們看看代碼吧:
bool CTeachLayer::ccTouchBegan( CCTouch* pTouch, CCEvent* pEvent ) { CCPoint touchPoint = pTouch->getLocation(); if (!CGlobal::s_bTeach) { return false; } //假設(shè)按鈕在(300,200)的位置,那么藍(lán)色矩形如下: CCRect m_obRect=CCRectMake( 250, 150, 100, 100); if (m_obRect.containsPoint(touchPoint)) { //得到藍(lán)色矩形的中心點(diǎn)(300,200) CCPoint pos=ccp(m_obRect.getMidX(),m_obRect.getMidY()); //這里要轉(zhuǎn)化為UI坐標(biāo)系(左上角為0,0點(diǎn)) pos=CCDirector::sharedDirector()->convertToUI(pos); //設(shè)置觸摸信息 pTouch->setTouchInfo(pTouch->getID(),pos.x,pos.y); return false; } return true; }
三.邏輯處理及代碼組織
這里我大概說(shuō)下新手引導(dǎo)的架構(gòu),代碼肯定貼不出來(lái),太多太亂,說(shuō)的不對(duì)的地方,歡迎大家拍磚吐槽!>_<
1.首先創(chuàng)建了一個(gè)CTeachLayer繼承自CCLayer,添加到游戲的最上層(UI層之上),記住,要先添加游戲的其層,最后添加CTeachLayer,可以保存全局指針!
2.用一個(gè)枚舉記下你要引導(dǎo)的所有步驟,在根據(jù)枚舉值去設(shè)置高亮的位置及觸摸區(qū)域!可以記下當(dāng)前引導(dǎo)的進(jìn)度,以方便下次繼續(xù)引導(dǎo)!
3.游戲邏輯中免不了要判斷引導(dǎo)(例:出第3波怪的時(shí)候引導(dǎo)玩家使用清屏道具),用全局的指針去設(shè)置引導(dǎo)的步驟!
4.引導(dǎo)完成后移除CTeachLayer,游戲開始!
- 如何使用CocosCreator對(duì)象池
- CocosCreator如何實(shí)現(xiàn)劃過(guò)的位置顯示紋理
- 整理CocosCreator常用知識(shí)點(diǎn)
- 全面講解CocosCreator熱更新
- CocosCreator經(jīng)典入門項(xiàng)目之flappybird
- CocosCreator通用框架設(shè)計(jì)之網(wǎng)絡(luò)
- 如何用CocosCreator實(shí)現(xiàn)射擊小游戲
- cocos2dx實(shí)現(xiàn)橡皮擦效果以及判斷是否擦除完畢
- 詳解iOS游戲開發(fā)中Cocos2D的坐標(biāo)位置關(guān)系
- 剖析iOS開發(fā)中Cocos2d-x的內(nèi)存管理相關(guān)操作
- 詳解CocosCreator項(xiàng)目結(jié)構(gòu)機(jī)制
相關(guān)文章
C++實(shí)現(xiàn)對(duì)RGB圖片進(jìn)行編碼的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何利用得到的RGB信息重新對(duì)RGB圖片進(jìn)行編碼,以及對(duì)其他圖片如BMP所得到的RGB信息進(jìn)行編碼從而得到*.jpg文件,感興趣的可以了解一下2023-05-05深入c++中臨時(shí)對(duì)象的析構(gòu)時(shí)機(jī)的詳解
本篇文章對(duì)c++中臨時(shí)對(duì)象的析構(gòu)時(shí)機(jī)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05利用C語(yǔ)言如何實(shí)現(xiàn)一些簡(jiǎn)單圖形的打印
這篇文章主要給大家介紹了關(guān)于利用C語(yǔ)言如何實(shí)現(xiàn)一些簡(jiǎn)單圖形的打印的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Matlab實(shí)現(xiàn)數(shù)據(jù)的動(dòng)態(tài)顯示方法
這篇文章主要為大家詳細(xì)介紹了Matlab使用Plot函數(shù)實(shí)現(xiàn)數(shù)據(jù)動(dòng)態(tài)顯示方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06C#使用反射加載多個(gè)程序集的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇C#使用反射加載多個(gè)程序集的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-06-06