【cocos2d-x 手游研發小技巧(1)自定義制作怪物傷害數值】


直插主題了,今天寫了一下午,早就想要寫這類似東西的,首先我不會選用CCLabelAtlas了,我直接用幀圖片做。

首先我們要准備素材,我先把素材帖出來給大家:

這個是一張比較全的素材圖,它包含了扣血的(第一行),加藍的(第二行),加血的(第三行);

我們先做加血的,先把加血圖片的單獨提出來,取出來大家好理解下面的代碼和算法!然后大家自己去拓展做加藍的加血的!

OK,素材准備好了,那么怎么去實現組合起來的數字呢?很簡單靠CCRect了;

CCSprite::create(imgurl,rect);

下面我就直接貼代碼了,代碼里面的注解寫得很詳細,我直接貼出來一邊描述大家一邊看;

我單獨建立了MakeNumbers.cpp,MakeNumbers.h;

MakeNumbers.h如下:

#include "cocos2d.h"

USING_NS_CC;
class MakeNumbers : public cocos2d::CCSprite
{
public:

    CCSprite* numbers;
    MakeNumbers(int attckmun);
    ~MakeNumbers(void);
};

MakeNumbers.cpp 如下 :

#include "MakeNumbers.h"
#include "../ImagePaths.h"
#include <string>
using namespace std;  
/*
這個類主要是顯示組合自定義圖片類型的傷害數值。
*/
MakeNumbers::MakeNumbers(int attckmun)
{
    //解析數值轉化為2中格式字符串string和CCString;
    char char_attckmun[100] = {0};
    sprintf(char_attckmun,"%d",attckmun,char_attckmun);
    //這個主要用途拿來作為字符和int之間的相互轉換
    CCString* numberstr = CCString::create(char_attckmun);
    //這個拿來截取字符
    string str = numberstr->getCString();
    
    //獲取整張素材圖片,圖片內容為-0123456789;
    CCSprite* number_all = CCSprite::create(p_makenumberbd);
    //獲取整張圖片長寬
    float allwight= number_all->getContentSize().width;
    float allhigth= number_all->getContentSize().height;
    //獲取單張圖片長寬
    float onewight = allwight/11;
    float onehigth = allhigth;
    //獲取第一個符號扣血-作為首張圖片的底圖
    CCRect imgrect_moren = CCRect(0,0,onewight,onehigth);
    numbers = CCSprite::create(p_makenumberbd,imgrect_moren);

    //循環解析出“-”符號號后面的具體數值傷害
    for (int i = 0; i < numberstr->length(); i++)
    {
        //依次解析每個數值大小
        string nownumber =  str.substr(0+i,1);
        CCString* cc_nownumber = CCString::create(nownumber);
        //將解析數值去尋找圖片
        CCRect imgrect_moren = CCRect(onewight*cc_nownumber->intValue()+onewight,0,onewight,onehigth);
        CCSprite* numbers_now = CCSprite::create(p_makenumberbd,imgrect_moren);
        //將得到的圖片依次尾追在“-”圖片得后面
        numbers_now->setPosition(ccp(numbers->getContentSize().width + numbers->getContentSize().width*i,numbers->getContentSize().height/2));
        numbers->addChild(numbers_now,2,10+i);
    }

}

MakeNumbers::~MakeNumbers(void)
{
}

OK,比較核心的邏輯就是這幾行代碼了:

numbers_now->setPosition(ccp(numbers->getContentSize().width + numbers->getContentSize().width*i,numbers->getContentSize().height/2));
numbers->addChild(numbers_now,2,10+i);

最后這個添加tag必須要添加上,因為后續再做動畫特效(隱藏,其他特效的不用)的時候必須得遍歷tag去隱藏!

OK以上代碼如果我們單獨跑起來,這樣使用,效果如下:

MakeNumbers* nowattcknumber = new MakeNumbers(attcknum);

 

還沒完!這不是我們最終想要的效果,我們還得加上動畫!!!

OK,cocos2d-x給我們提供的延時動作,動畫方法真的太棒了,我們組合起來使用真是很完美的特效!

這里我用到了如下動畫:放大縮小,淡出淡入,還有賽貝爾曲線,最后執行移除回調函數,不消耗內存,用完就釋放!

下面我就直接貼上動畫的代碼:

/*
怪物傷害數字動畫特效
*/
void SpiritsMonster::showattcknumber(int attcknum,CCSprite* monster)
{
    if(attcknum>0)
    {
        //解析數值轉化為2中格式字符串string和CCString;
        char char_attckmun[100] = {0};
        sprintf(char_attckmun,"%d",attcknum,char_attckmun);
        //這個主要用途拿來作為字符和int之間的相互轉換
        CCString* numberstr = CCString::create(char_attckmun);
        //組合傷害數值
        MakeNumbers* nowattcknumber = new MakeNumbers(attcknum);
        //設置在怪物頭上一半距離彈出傷害
        nowattcknumber->numbers->setPosition(ccp(monster->getContentSize().width/2,monster->getContentSize().height*1.5f));
        //設置動畫賽貝爾曲線
        ccBezierConfig bezier;
        bezier.controlPoint_1=CCPointMake(50,monster->getContentSize().height*2.0f);
        bezier.controlPoint_2=CCPointMake(monster->getContentSize().width/2,monster->getContentSize().height);
        CCActionInterval* bezier_act = CCBezierTo::create(2.5f,bezier);
        //設置動畫彈出放大和縮小
        CCActionInterval* scale_act = CCScaleTo::create(2.0f,1.5f);
        CCActionInterval* scale_actby = CCScaleBy::create(1.0f,2.0f);
        //設置動畫淡出淡入(開始顯示,最后隱藏)
        CCActionInterval* fade_actby = CCFadeIn::create(2.0f);
        CCActionInterval* fade_actby2 = CCFadeOut::create(2.0f);
        //最后執行移除回調函數,不消耗內存,用完就釋放
        CCFiniteTimeAction *actbackfun = CCCallFuncO::create(monster, callfuncO_selector(SpiritsMonster::ShowNumberCallBack_setvisible),monster);
        nowattcknumber->numbers->runAction(CCSequence::create(scale_actby,scale_actby->reverse(),NULL));
        nowattcknumber->numbers->runAction(fade_actby2);
        for (int i = 0; i < numberstr->length(); i++)
        {
            CCActionInterval* fade_actby_back = fade_actby->reverse();
            nowattcknumber->numbers->getChildByTag(10+i)->runAction(fade_actby_back);    
        }
        nowattcknumber->numbers->runAction(CCSequence::create(bezier_act,actbackfun,NULL));
        //添加到怪物Body中
        monster->addChild(nowattcknumber->numbers,10,12);
    }
}

執行回調的函數如下:

void SpiritsMonster::ShowNumberCallBack_setvisible(CCObject* obj)
{
    CCSprite* monster = (CCSprite*)obj;
    //移除傷害數值
    monster->removeChildByTag(12);
}

大家在剛才提到的addchild里面加tag的思路在這邊用到了,需要遍歷一下去隱藏一下!

for (int i = 0; i < numberstr->length(); i++)
{
     CCActionInterval* fade_actby_back = fade_actby->reverse();
     nowattcknumber->numbers->getChildByTag(10+i)->runAction(fade_actby_back);    
}

所有代碼都貼完了,然后解釋一下我問啥不用CCLabelAtlas,而使用自定義的方式去實現,因為CCSprite圖片+動作的效果

非常贊,而且易拓展,自己控制起來非常方便,最好說一下我的代碼風格,我這些代碼有的還需要重構一下,封裝起來會很好

用,我的命名由於英語實在是太差了大部分還使用拼音,大家多多包含,看懂思路自己去重寫一遍收獲會更多,由於英語不好

曾經有很好外企工作機會沒去成。哈哈,題外話了都是,下面來看看這很贊的效果!

 

先放大,同時沿賽貝爾曲線飄一段,然后一遍縮小一遍隱藏,最后自身銷毀!

我建了一個QQ群:和大家一起分享cocos2dx開發經驗【41131516】


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM