程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 根據CocosBuilder文件自動生成代碼

根據CocosBuilder文件自動生成代碼

編輯:C++入門知識

本文主要講述怎樣根據Cocosbuilder生成的ccb文件自動生成相應的代碼,主要以生成cocos2dx對應的C++文件為例子來說明。

 

 


cocosbuilder是一個非常好用的開源工具,可以用來編輯ui布局,粒子系統,簡單的幀動畫等。在編輯器中可以設置UI回調函數名,綁定編輯對象到Owner或者Doc root上以及為自定義的對象設置自定義的屬性。以上三點都需要相應的代碼來支持。因此在編輯完成游戲場景後,一定要寫相應的代碼。但是寫相關的代碼是比較繁瑣的,很容易出現錯誤。

如果在場景編輯完成後,能根據場景文件自動生成代碼框架將會節省不少工作量,並且減少出錯的概率。下面分三個部分來一一說明如何實現自動生成代碼,第一部分將會大體描述如何綁定代碼,第二部分分析如何自動生成代碼,第三部分給出代碼實現

一 場景編輯器中控件與代碼綁定

1.菜單回調函數,如下圖設置,可以指定一個Selector和Target,在編輯器中設置後,將對應的target對象的某一個擁有特定簽名的函數與selector指定的字符串綁定起來後,當菜單按下時,就會回調的相應的函數。

 

我們先來研究一下,在Cocos2dx中是如何將MenuItem的回調綁定到相應代碼中的。

a.假設Document root對應的類為TestAutoGenLayer,為了實現綁定TestAutoGenLayer必須繼承一個

cocos2d::extension::CCBSelectorResolver,然後實現 函數

    virtual cocos2d::SEL_MenuHandler onResolveCCBCCMenuItemSelector(cocos2d::CCObject * pTarget, cocos2d::CCString * pSelectorName);

在該函數中完成代碼綁定。

b.綁定代碼如下:


[cpp]
SEL_MenuHandler TestAutoGenLayer::onResolveCCBCCMenuItemSelector(cocos2d::CCObject *pTarget, cocos2d::CCString *pSelectorName) 

CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this,"BackPressed",TestAutoGenLayer::BackPressed); 
return false; 

SEL_MenuHandler TestAutoGenLayer::onResolveCCBCCMenuItemSelector(cocos2d::CCObject *pTarget, cocos2d::CCString *pSelectorName)
{
CCB_SELECTORRESOLVER_CCMENUITEM_GLUE(this,"BackPressed",TestAutoGenLayer::BackPressed);
return false;
}

上面代碼將selector指定的值”BackPressed“與TestAutoGenLayer::的BackPressed函數綁定起來。(注:Selector的值可以函數名不相同)


c. BackPressed的代碼框架如下

 

[cpp]
void TestAutoGenLayer::BackPressed(cocos2d::CCObject * pSender) 

//在這裡實現回調功能  

void TestAutoGenLayer::BackPressed(cocos2d::CCObject * pSender)
{
//在這裡實現回調功能
}

2.ControlButton回調

假設一個ControlButton在cocosbuild中有如下設置,

 


Document root還是TestAutoGenLayer類,在該類中實現CCBSelectorResolver的onResolveCCBCCControlSelector函數,假設代碼如下


[cpp]
SEL_CCControlHandler TestAutoGenLayer::onResolveCCBCCControlSelector(cocos2d::CCObject *pTarget, cocos2d::CCString *pSelectorName) 

    CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this,"DoNotPress",TestAutoGenLayer::DoNotPress); 
    return false; 

SEL_CCControlHandler TestAutoGenLayer::onResolveCCBCCControlSelector(cocos2d::CCObject *pTarget, cocos2d::CCString *pSelectorName)
{
 CCB_SELECTORRESOLVER_CCCONTROL_GLUE(this,"DoNotPress",TestAutoGenLayer::DoNotPress);
 return false;
}

DonotPressMe的代碼框架如下


[cpp]
void TestAutoGenLayer::DoNotPress(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent) 

//在這裡實現控件回調功能  

void TestAutoGenLayer::DoNotPress(CCObject * pSender, cocos2d::extension::CCControlEvent pCCControlEvent)
{
//在這裡實現控件回調功能
}

3.將場景中的對象賦值給指定的對象,選擇一個對象後,修改code connection屬性,如下圖

 


可以選擇將一個對象賦值給 Document root或者是owner,指定一個綁定名字即可,下面綁定到Document root為例,假設root是TestAutoGenLayer類,被綁定的對象為CClabelTTF,為了實現綁定,a.TestAutoGenLayer必須承繼於cocos2d::extension::CCBMemberVariableAssigner,並且實現方法onAssignCCBMemberVariable,b.TestAutoGenLayer 必須定一個類型為CCLabelTTF的成員變量

 


綁定代碼段如下


[cpp]
bool TestAutoGenLayer::onAssignCCBMemberVariable(cocos2d::CCObject *pTarget, cocos2d::CCString *pMemberVariableName, cocos2d::CCNode *pNode) 
{   CCB_MEMBERVARIABLEASSIGNER_GLUE(this,"m_String2",CCLabelTTF*,this->m_String2); 
    return false; 

bool TestAutoGenLayer::onAssignCCBMemberVariable(cocos2d::CCObject *pTarget, cocos2d::CCString *pMemberVariableName, cocos2d::CCNode *pNode)
{ CCB_MEMBERVARIABLEASSIGNER_GLUE(this,"m_String2",CCLabelTTF*,this->m_String2);
 return false;
}

4.為自定義類型設置custom properties,具體在編輯中如何設置custom propertyies就不在些描述了,下面只專主如何將自定義屬性綁定到代碼中,cocosbuilder支持的自定義類型有4種:int,float,string,bool。假設在cocosbuilder中設置了4個自定義類型的變量,分別是

int 類型的m_intVal;

float類型的m_floatVal;

string類型的m_stringVal;

bool類型的m_boolVar;

為了實現綁定到類TestAutoGenLayer,

a.該類必須實現類cocos2d::extension::CCBMemberVariableAssigner的接口onAssignCCBCustomProperty

b.定義與自定義類型相關的變量

 


綁定代碼如下:


[cpp]
bool TestAutoGenLayer::onAssignCCBCustomProperty(cocos2d::CCObject *pTarget, const char *pMemberVariableName, cocos2d::extension::CCBValue *pCCBValue) 

    if (pTarget == this) 
    { 
        if (0 == strcmp(pMemberVariableName, "m_intvar")){ 
            m_intvar = pCCBValue->getIntValue(); 
            return true; 
        } 
        if (0 == strcmp(pMemberVariableName, "m_floatVar")){ 
            m_floatVar = pCCBValue->getFloatValue(); 
            return true; 
        } 
        if (0 == strcmp(pMemberVariableName, "m_stringVar")){ 
            m_stringVar = pCCBValue->getStringValue(); 
            return true; 
        } 
        if (0 == strcmp(pMemberVariableName, "m_bool")){ 
            m_bool = pCCBValue->getBoolValue(); 
            return true; 
        } 
 
    } 
    return false; 

bool TestAutoGenLayer::onAssignCCBCustomProperty(cocos2d::CCObject *pTarget, const char *pMemberVariableName, cocos2d::extension::CCBValue *pCCBValue)
{
    if (pTarget == this)
    {
  if (0 == strcmp(pMemberVariableName, "m_intvar")){
   m_intvar = pCCBValue->getIntValue();
   return true;
  }
  if (0 == strcmp(pMemberVariableName, "m_floatVar")){
   m_floatVar = pCCBValue->getFloatValue();
   return true;
  }
  if (0 == strcmp(pMemberVariableName, "m_stringVar")){
   m_stringVar = pCCBValue->getStringValue();
   return true;
  }
  if (0 == strcmp(pMemberVariableName, "m_bool")){
   m_bool = pCCBValue->getBoolValue();
   return true;
  }

 }
 return false;
}

 

二. 如何實現自動生成代碼

 

 

         根據上面的分析,我們知道一共有四種類型的綁定代碼需要生成,每種類型的綁定都需要生成聲明和實現(.h文件與.cpp文件),另外還要生成類的定義、構造函數及文件的尾部。下面來一一分析需要生成代碼。

1.    MenuItem回調

a)       頭文件:生成Selector對應的函數聲明

b)       cpp文件,生成空的Selector函數體,

c)       cpp文件 生成綁定代碼

2.    ControlButton回調

a)       頭文件:生成Selector對應的函數聲明

b)       cpp文件,生成空的Selector函數體,

c)       cpp文件 生成綁定代碼

3.    場景對象賦值到宿主

a)       頭文件,生成變量聲明

b)       cpp文件,生成綁定代碼

c)       構造函數,變量賦初值

4.    自定義變量賦值到宿主

a)       頭文件,生成變量聲明

b)       cpp文件,生成綁定代碼

c)       構造函數,變量賦初值

5.    雜項

a)       類定義生成

b)       構造函數生成

c)       頭文件尾部生成

要生成這些代碼需要些什麼信息呢,為了方便說明,直接上代碼

 

[cpp]
struct TypeName { 
    TypeName(const std::string& t="",const std::string& n="") 
    :type(t),name(n){} 
    std::string type; 
    std::string name; 
}; 
 
    std::stringm_className;                        //要生成的類名  
    std::string m_baseClass;                        //生成類的父類  
    std::vector<TypeName>m_listAssignMember;       //需要賦值的場景對象  
    std::vector<TypeName>m_listCutomProperty;      //需要賦值的自定義變量  
    std::vector<std::string>m_listCContorlCallBack;//menu回調函數名  
    std::vector<std::string>m_listMenuCallBack;    //control回調函數名 

struct TypeName {
    TypeName(const std::string& t="",const std::string& n="")
    :type(t),name(n){}
    std::string type;
    std::string name;
};

    std::stringm_className;                        //要生成的類名
    std::string m_baseClass;                        //生成類的父類
    std::vector<TypeName>m_listAssignMember;       //需要賦值的場景對象
    std::vector<TypeName>m_listCutomProperty;      //需要賦值的自定義變量
    std::vector<std::string>m_listCContorlCallBack;//menu回調函數名
    std::vector<std::string>m_listMenuCallBack;    //control回調函數名

 

 這些信息從什麼地方可以獲取呢,只用解析cocosbuilder生成的ccb文件就可以得到了。

有了上述的信息,我們再定義一些代碼模板,替換和復制代碼模板就可以生成相關代碼了。 以類的定義生成來說明。類的代碼模板如下

 

 


[cpp]
//  %class_name%.h  
//   
//  
//  this code is auto generate by the toolcreated by neo. Email [email protected]  
//  
//  
  
#ifndef __autogen_ccbuilder__%class_name%__  
#define__autogen_ccbuilder__%class_name%__  
  
#include"cocos2d.h"  
#include"cocos-ext.h"  
  
class %class_name% 
:publiccocos2d::%base_class% 
, publiccocos2d::extension::CCBSelectorResolver 
, publiccocos2d::extension::CCBMemberVariableAssigner 
, publiccocos2d::extension::CCNodeLoaderListener 
  

public: 
    %class_name%() 
:%base_class%() 

//  %class_name%.h
//
//
//  this code is auto generate by the toolcreated by neo. Email [email protected]
//
//
 
#ifndef __autogen_ccbuilder__%class_name%__
#define__autogen_ccbuilder__%class_name%__
 
#include"cocos2d.h"
#include"cocos-ext.h"
 
class %class_name%
:publiccocos2d::%base_class%
, publiccocos2d::extension::CCBSelectorResolver
, publiccocos2d::extension::CCBMemberVariableAssigner
, publiccocos2d::extension::CCNodeLoaderListener
 
{
public:
    %class_name%()
:%base_class%() 

在生成代碼時,讀入代碼模板,將%class_name%替換為m_className,%base_class%替換為m_baseClass就可以了。

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved