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;    //椭圆的a
51     int mCircleB;    //椭圆的b
52     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     else
185     {
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 radian
201         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 }

 

posted @ 2014-06-21 23:50  Reise  阅读(1313)  评论(0编辑  收藏  举报