【cocos2d-x 手游研發----界面UI設計】


簡單探討一下如何在cocos2d-x的游戲引擎里面去制作各做交互UI界面,常見的UI如下:

人物頭像,血條值,經驗條,技能按鈕,以及各種玩家交互的界面按鈕:背包,人物屬性,門派,等;

類似上面的圖示交互UI,他們是懸浮於窗體上的。那么按照我現在做的層級架構就是這些UI操作,是不屬於任何CCObject的,或者被繼承的;

回到第一篇我對整個架構的分析,這些交互UI屬於事件,和任務類型!對於手游UI來說這類似的UI設計更為嚴格,因為玩家位移的交互方式,

就是點擊屏幕,我們要虛擬化各種按鍵去實現各種操作。

先把以上描述的基本UI在界面上畫出來:

BaseUI.cpp , BaseUI.h 類

   ui_exp = BaseUI::create(p_expbd);
    ui_exp ->setPosition(ccp(150,ui_exp->getContentSize().height+20));
    layer->addChild(ui_exp,1);

    ui_skillbar = BaseUI::create(p_skillbarbd);
    ui_skillbar ->setPosition(ccp(size.width-ui_skillbar->getContentSize().width+35,ui_skillbar->getContentSize().height));
    layer->addChild(ui_skillbar,3);

    ui_skill_skill0 = BaseUI::create(p_skill_nv0);
    ui_skill_skill0 ->setPosition(ccp(size.width-ui_skill_skill0->getContentSize().width+7,ui_skill_skill0->getContentSize().height+22));
    layer->addChild(ui_skill_skill0,1,801);

我們需要通過觸摸點擊去識別判斷我們的UI坐標是否被用戶點擊:

 

CCRect BaseUI::rect_skill0()
{
    //獲取精靈區域大小
    return CCRectMake(ui_skill_skill0->getPositionX()- ui_skill_skill0->getContentSize().width  * ui_skill_skill0->getAnchorPoint().x,ui_skill_skill0->getPositionY()-ui_skill_skill0->getContentSize().height* ui_skill_skill0->getAnchorPoint().y,ui_skill_skill0->getContentSize().width, ui_skill_skill0->getContentSize().height); 

}

void BaseUI::isTouchInside(CCTouch *pTouch)
{ 

    CCPoint localPoint = pTouch->getLocation();
    CCRect rc = rect_skill0();
    bool isTouched = rc.containsPoint(localPoint);
    if (isTouched == true) {
        CCLog(FontChina::G2U("1111111111111111111!"));
        if(touch_skill0_flag!=true)
        {
            touch_skill0_flag = true;
        }
    }
}

我們設置了變量如:技能的變量(touch_skill0_flag)來在其他地方去實現技能釋放,執行釋放操作的的關聯是在baseMap上面,因為之前我們的邏輯關系上,玩家是屬於地圖層級,那么我們便可以很方便的去控制玩家釋放技能對怪物的操作交互;

//啟動玩家操作監聽器
nowmap->schedule(schedule_selector(Maps_Diyu::makeroleAttack)); 

讓在地圖層上面我們需要啟動監聽器去實現技能得操作,那么我們就如下去寫:

void Maps_Diyu::makeroleAttack(float times)  
{  
    if(touch_skill0_flag==true)
    {
        //先去尋找主角周圍的敵人,選擇最近的一個為目標;
        CCPoint playerpoint =  this->getChildByTag(999)->getPosition();
        int attck_reatR = 200;
        int nowtag = -1;
        CCPointArray* attck_pointlist = CCPointArray::create(0);
        for (int i = 0; i < 15; i++)
        {
            CCRect* attck_rect = new CCRectMake(this->getChildByTag(999)->getPosition().x-attck_reatR/2,this->getChildByTag(999)->getPosition().y-attck_reatR/2,attck_reatR,attck_reatR);
            if(this->getChildByTag(100+i)!=NULL)
            {
                if(attck_rect->containsPoint(this->getChildByTag(100+i)->getPosition())==true)
                {
                    CCLog(FontChina::G2U("在主角攻擊范圍"));
                    attck_pointlist->addControlPoint(this->getChildByTag(100+i)->getPosition());
                    nowtag=100+i;
                    break;
                }
            }
        }
        if(nowselects==true)
        {
                //攻擊默認怪物
                CCPoint attck_point = this->getChildByTag(nowselecttag)->getPosition();
                basedatas = new GetNPCData();
                basedatas->GetRoleData(); 
                basedatas->role_player.acttodo=attack;
                SpiritsPlayer::attckTomap_dir(ccp(attck_point.x,attck_point.y),(CCSprite*)this->getChildByTag(999),basedatas->role_player);
                SkillEffects* role_skill = new SkillEffects(ccp((int)attck_point.x,(int)attck_point.y),basedatas->role_player,(0.2f+CCRANDOM_0_1()),12,3,0);
            
                this->addChild(role_skill->effects_main,1000,50);
                role_skill->release();
                SpiritsMonster::showattcknumber(899,(CCSprite*)this->getChildByTag(nowselecttag));
        }
        else
        {
            if(attck_pointlist->count()>0)
            {
                //攻擊默認怪物
                CCPoint attck_point = attck_pointlist->getControlPointAtIndex(0);
                //該技能是否先移動一定距離,再進行攻擊,還是直接釋放魔法攻擊
                basedatas = new GetNPCData();
                basedatas->GetRoleData(); 
                basedatas->role_player.acttodo=attack;
                SpiritsPlayer::attckTomap_dir(ccp(attck_point.x,attck_point.y),(CCSprite*)this->getChildByTag(999),basedatas->role_player);
                SkillEffects* role_skill = new SkillEffects(ccp((int)attck_point.x,(int)attck_point.y),basedatas->role_player,(0.2f+CCRANDOM_0_1()),12,3,0);
                
                this->addChild(role_skill->effects_main,1000,50);
                role_skill->release();
                SpiritsMonster::showattcknumber(899,(CCSprite*)this->getChildByTag(nowtag));
            }
        }
        touch_skill0_flag=false;
    }

}  

上面的寫法,又再一次利用了怪物AI里面的一些基本邏輯,不過這套邏輯是需要玩家去手動觸發的;

 

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

 


免責聲明!

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



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