首页 > 代码库 > cocos2dx实现环形角色选择界面

cocos2dx实现环形角色选择界面

数据结构采用双向循环链表。由候选角色组成链表的节点,将链表中的节点在屏幕上按照椭圆分布。

 .h:

 1 //链表节点——候选角色 2 class CandidateRole :public CCNode{ 3 public: 4     CandidateRole(); 5     ~CandidateRole(); 6     virtual bool init(const char* name); 7     static CandidateRole* create(const char* name); 8     CandidateRole* mpNextRole; //节点右面角色的指针 9     CandidateRole* mpForeRole;  //..左..........     10 11      void setPositionIndex(int );12      int getPositionIndex();   13 14     int mDistance;     //到椭圆最低点的距离15     int mPositionIndex;     //节点在链表中的序号16     int mNextPositionX;    17     int mNextPositionY;18     int mColorR;19     int mColorG;20     int mColorB;21     CCArmature* mpArmature;22     bool mbIsSelected;   // 是否被选中23 24 };25 26 27 //由候选角色组成的链表,在屏幕上成椭圆分布28 class CircleStage :public CCNode{29 30 public:31     CircleStage();32     ~CircleStage();33     virtual bool init();34     35     CREATE_FUNC(CircleStage);36     void addRole(CandidateRole *);    //添加一个角色到链表37     void changeToNext();    //顺时针旋转38     void changeToFore();    //逆时针旋转39     40     bool isOnAction();41     void actionEnd();42 43 private:44     bool mbOnAction;45     int mRoleNum;46     CandidateRole* mpCurrentRole;     //操作链表用的指针47     CandidateRole* mpHead;48     CandidateRole* mpLast;49     CandidateRole* mpSelectRole;    //被选中的角色,在椭圆最低点50     int mCircleA;    //椭圆的a51     int mCircleB;    //椭圆的b52     void updateColor();    //更新每个节点的明暗,越远越暗53     void updateZorders();    //更新遮盖关系54         void updateZordersCallBack();55     void updateDistances();    //更新每个节点到中央节点的距离56     void initAppearance();    //初始化颜色和缩放57     58 };        

 

 

.cpp:

  1 CandidateRole::CandidateRole()  2 {  3   4 }  5 CandidateRole::~CandidateRole()  6 {  7   8 }  9 bool CandidateRole::init(const char* name) 10 { 11  12     mPositionIndex=0; 13     mbIsSelected=false; 14     mDistance=0; 15     mColorB=255; 16     mColorG=255; 17     mColorR=255; 18      19     mpArmature = CCArmature::create(name); 20     this->addChild(mpArmature); 21  22     return true; 23 } 24  25 CandidateRole* CandidateRole::create(const char* name) 26 { 27     CandidateRole* pRet = new CandidateRole(); 28     if (pRet && pRet->init(name)) 29     { 30         pRet->autorelease(); 31     } 32     else 33     { 34         CC_SAFE_DELETE(pRet); 35     } 36     return pRet; 37 } 38  39 void CandidateRole::setPositionIndex(int index) 40 { 41     mPositionIndex=index; 42 } 43  44 int CandidateRole::getPositionIndex() 45 { 46     return mPositionIndex; 47  48 } 49  50 CircleStage::CircleStage() 51 { 52  53 } 54  55 CircleStage::~CircleStage() 56 { 57  58 } 59  60 bool CircleStage::init() 61 { 62  63     mCircleA=ScreenWidth*0.4; 64     mCircleB=80; 65     mRoleNum=0; 66     mpHead=NULL; 67     mbOnAction=false; 68     for(int i=0;i<8;i++) 69     { 70         CandidateRole* role=CandidateRole::create("role"); 71         this->addRole(role); 72  73     } 74     updateDistances(); 75     updateZorders(); 76     initAppearance(); 77     return true; 78  79 } 80 void CircleStage::updateColor() 81 { 82     mpCurrentRole=mpSelectRole; 83     for (int i=0;i<mRoleNum;i++) 84     { 85         mpCurrentRole->mColorR=255; 86         mpCurrentRole->mColorG=255; 87         mpCurrentRole->mColorB=255; 88         for (int j=0;j<mpCurrentRole->mDistance;j++) 89         { 90              91             mpCurrentRole->mColorR*=0.6; 92             mpCurrentRole->mColorG*=0.6; 93             mpCurrentRole->mColorB*=0.6; 94         } 95         mpCurrentRole->mpArmature->setColor(ccc3(mpCurrentRole->mColorR,mpCurrentRole->mColorG,mpCurrentRole->mColorB)); 96         mpCurrentRole=mpCurrentRole->mpNextRole; 97     } 98 } 99 100 void CircleStage::updateDistances()101 {102     mpCurrentRole=mpSelectRole;103     int distance=0;104     for (int i=0;i<=mRoleNum/2;i++)105     {106     mpCurrentRole->mDistance=distance;107     ++distance;108     mpCurrentRole=mpCurrentRole->mpNextRole;109 110     }111     mpCurrentRole=mpSelectRole;112     distance=0;113     for (int i=0;i<=mRoleNum/2;i++)114     {115     mpCurrentRole->mDistance=distance;116     ++distance;117     mpCurrentRole=mpCurrentRole->mpForeRole;118     }119 120     mpSelectRole->mDistance=0;121 }122 void CircleStage::initAppearance()123 {124     mpCurrentRole=mpSelectRole;125 126     for (int i=0;i<mRoleNum;i++)127     {128         double scale=1;129         130         for (int j=0;j<mpCurrentRole->mDistance;j++)131         {132             scale*=0.8;133             mpCurrentRole->mColorR*=0.6;134             mpCurrentRole->mColorG*=0.6;135             mpCurrentRole->mColorB*=0.6;136         }137         mpCurrentRole->setScale(scale);138 139         mpCurrentRole->mpArmature->setColor(ccc3(mpCurrentRole->mColorR,mpCurrentRole->mColorG,mpCurrentRole->mColorB));140         mpCurrentRole=mpCurrentRole->mpNextRole;141     }142     mpSelectRole->setScale(1.0f);143 144 }145 146 void CircleStage::updateZorders()147 {148     mpSelectRole->setZOrder(mRoleNum);149     mpSelectRole->mDistance=0;150     mpCurrentRole=mpSelectRole;151     152     for (int i=0;i<=mRoleNum/2;i++)153     {154 155         mpCurrentRole->setZOrder(mRoleNum-mpCurrentRole->mDistance);156         mpCurrentRole=mpCurrentRole->mpNextRole;157     }158     for (int i=mRoleNum/2+1;i<mRoleNum;i++)159     {160         161         mpCurrentRole->setZOrder(abs(mRoleNum/2-mpCurrentRole->mDistance));162         mpCurrentRole=mpCurrentRole->mpNextRole;163     }164 165 }166 167 168 169 170 void CircleStage::addRole(CandidateRole *newRole)171 {172     if (!mpHead)173     {174         mpHead=newRole;175         this->addChild(newRole);176         mpLast=mpHead;177         mpLast->mpNextRole=mpHead;178         mpHead->mpForeRole=mpHead;179         mpCurrentRole=mpHead;180         mRoleNum++;181         mpCurrentRole->setPositionIndex(mRoleNum);182         mpSelectRole=newRole;183     } 184     else185     {186         mpLast->mpNextRole=newRole;187         newRole->mpNextRole=mpHead;188         newRole->mpForeRole=mpLast;189         mpHead->mpForeRole=newRole;190         this->addChild(newRole);191         mpLast=newRole;192         mRoleNum++;193         newRole->setPositionIndex(mRoleNum);194     }195     int x,y;196     double t;197     while(1)198     {    199         t=360/mRoleNum*(mpCurrentRole->getPositionIndex()-1)-90;200         t=t*3.14/180;//convert t to radian201         x=mCircleA*cos(t);202         y=mCircleB*sin(t);203         mpCurrentRole->setPositionX(x);204         mpCurrentRole->setPositionY(y);205         mpCurrentRole=mpCurrentRole->mpNextRole;206 207         if (mpCurrentRole==mpHead)208         {209             break;210         }211 212     }213 }214 215 void CircleStage::changeToNext() //从右向左216 {217     mpSelectRole=mpSelectRole->mpNextRole;218     CCCallFunc* callFuncActionEnd = CCCallFunc::create(this,callfunc_selector(CircleStage::actionEnd));219     CCCallFunc* callUpdateZorder = CCCallFunc::create(this,callfunc_selector(CircleStage::updateZordersCallBack));220     if (mpCurrentRole->mpNextRole)221     {222         223         mpSelectRole->setZOrder(mRoleNum);224         for (int i=0;i<mRoleNum;i++)225         {226     227             mpCurrentRole->mNextPositionX=mpCurrentRole->mpForeRole->getPositionX();228             mpCurrentRole->mNextPositionY=mpCurrentRole->mpForeRole->getPositionY();229             mbOnAction=true;230             CCMoveTo *moveToNext=CCMoveTo::create(0.4f,ccp(mpCurrentRole->mNextPositionX,mpCurrentRole->mNextPositionY));231             CCScaleTo *scaleToFore=CCScaleTo::create(0.4f,mpCurrentRole->mpForeRole->getScale());232             CCFiniteTimeAction*  spawnAction = CCSpawn::create(moveToNext,scaleToFore,NULL);233         234             CCSequence* actions = CCSequence::create(spawnAction,callUpdateZorder,callFuncActionEnd,NULL);235             mpCurrentRole->runAction(actions);236             237             mpCurrentRole=mpCurrentRole->mpNextRole;238         239         }240         updateDistances();241         updateColor();242     243     }244 245 246 }247 248 void CircleStage::updateZordersCallBack()249 {250   updateZorders();251 }252 void CircleStage::actionEnd()253 {254     mbOnAction=false;255 256 }257 258 void CircleStage::changeToFore() //从左向右259 {260     mpSelectRole=mpSelectRole->mpForeRole;261     CCCallFunc* callFuncActionEnd = CCCallFunc::create(this,callfunc_selector(CircleStage::actionEnd));262     263     if (mpCurrentRole->mpForeRole)264     {265         for (int i=0;i<mRoleNum;i++)266         {267             mpCurrentRole->mNextPositionX=mpCurrentRole->mpNextRole->getPositionX();268             mpCurrentRole->mNextPositionY=mpCurrentRole->mpNextRole->getPositionY();269             mbOnAction=true;270         271             CCMoveTo *moveToFore=CCMoveTo::create(0.4f,ccp(mpCurrentRole->mNextPositionX,mpCurrentRole->mNextPositionY));272             CCScaleTo *scaleToFore=CCScaleTo::create(0.4f,mpCurrentRole->mpNextRole->getScale());273             CCFiniteTimeAction*  spawnAction = CCSpawn::create(moveToFore,scaleToFore,NULL);274             CCSequence* actions = CCSequence::create(spawnAction,callFuncActionEnd,NULL);275             mpCurrentRole->runAction(actions);276             mpCurrentRole=mpCurrentRole->mpNextRole;277 278         }279         updateDistances();280         updateZorders();281         updateColor();282     283     }284 }285 286 bool CircleStage::isOnAction()287 {288     return mbOnAction;289 }