Cocos2d-x2.0 TestCpp框架源码分析
[本版教程使用的Cocos2d-x版本为cocos2d-2.0-x-2.0.2]
好的引擎,会提供一系列完整的功能示例,Cocos2d-x之所以能得到很多人的喜爱,其重要的原因是它提供了丰富而易学的示例。在cocos2d-2.0-x-2.0.2中这些示例被放在一个名叫TestCpp的工程中,为了更好的学习Cocos2d-x的功能示例,我们今天来学习一下这个工程的框架结构。
在VS的解决方案里展开TestCpp工程,其下有43个示例目录,除此之前还有几个文件:
AppDelegate.h/cpp : 程序控制类AppDelegate 。
controller.h/cpp:示例场景管理类TestController,用于显示所有示例的菜单。
testBasic.h/cpp:示例场景基类TestScene,用于返回到主界面场景。
testResource.h:文件资源名称字符串定义头文件
tests.h:示例总头文件
main.h/cpp:主函数及头文件
所有的示例都是写在单独的由TestScene派生场景类中,在这些场景中加入一些由CCLayer派生的示例对象来实现相应功能的展示。
与HelloWorld一样,我们需要在main.cpp中创建AppDelegate实例,并设置窗口大小,启动游戏程序。
[cpp] view plain copy
1. #include "main.h"
2. #include "AppDelegate.h"
3. #include "CCEGLView.h"
4. USING_NS_CC;
5. //WIN32程序主函数
6. int APIENTRY _tWinMain(HINSTANCE hInstance,
7. HINSTANCE hPrevInstance,
8. LPTSTR lpCmdLine,
9. int nCmdShow)
10. {
11. UNREFERENCED_PARAMETER(hPrevInstance);
12. UNREFERENCED_PARAMETER(lpCmdLine);
13. //实例化一个Cocos2d-x程序对象
14. AppDelegate app;
15. //创建OpenGL视窗并设置窗口大小
16. CCEGLView* eglView = CCEGLView::sharedOpenGLView();
17. eglView->setFrameSize(480, 320);
18. //运行程序对象
19. return CCApplication::sharedApplication()->run();
20. }
boolAppDelegate::applicationDid。FinishLaunching()函数中创建场景并运行场景
[cpp] view plain copy
1. bool AppDelegate::applicationDidFinishLaunching()
2. {
3. // 取得当前显示设备指针并设置其OpenGL视窗
4. CCDirector *pDirector = CCDirector::sharedDirector();
5. pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
6. //取得当前运行硬件平台
7. TargetPlatform target = getTargetPlatform();
8. //如果是IPAD
9. if (target == kTargetIpad)
10. {
11. //如果能启动高清屏,使用高精度资源,否则使用一般精度资源
12. if (pDirector->enableRetinaDisplay(true))
13. {
14. "ipadhd");
15. }
16. else
17. {
18. "ipad");
19. }
20. }
21. //如果是Iphone
22. else if (target == kTargetIphone)
23. {
24. //如果能启动高清屏,使用高精度资源
25. if (pDirector->enableRetinaDisplay(true))
26. {
27. "hd");
28. }
29. }
30.
31. // 设置FPS信息显示
32. true);
33.
34. //设置帧间隔时间
35. pDirector->setAnimationInterval(1.0 / 60);
36. //在这里创建一个场景
37. CCScene * pScene = CCScene::create();
38. //实例化一个TestController,它是一个CCLayer。
39. new TestController();
40. //设置由内存管理器来进行自动回收,不必手动DELETE
41. pLayer->autorelease();
42. //将它放置到场景中
43. pScene->addChild(pLayer);
44. //运行这个新创建的场景。
45. pDirector->runWithScene(pScene);
46.
47. return true;
48. }
下面我们来看一下testBase.h/cpp,这里面有一个所有示例都要用到的场景基类TestScene。
[cpp] view plain copy
1. #ifndef _TEST_BASIC_H_
2. #define _TEST_BASIC_H_
3. //Cocos2d头文件
4. #include "cocos2d.h"
5. //使用Cocos2d命名空间
6. USING_NS_CC;
7. using namespace std;
8.
9. class TestScene : public CCScene
10. {
11. public:
12. //构造
13. bool bPortrait = false);
14. //场景被加载时的回调函数
15. virtual void onEnter();
16. //自定义的虚函数,用于运行场景。
17. virtual void runThisTest() = 0;
18. //返回主界面的菜单按钮响应回调函数。
19. virtual void MainMenuCallback(CCObject* pSender);
20. };
21.
22. #endif
cpp文件:
[cpp] view plain copy
1. #include "testBasic.h"
2. #include "controller.h"
3. //构造函数
4. TestScene::TestScene(bool bPortrait)
5. {
6.
7. CCScene::init();
8. }
9. //场景被加载时的回调函数
10. void TestScene::onEnter()
11. {
12. CCScene::onEnter();
13.
14. //#if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
15. // CCLabelBMFont* label = CCLabelBMFont::create("MainMenu", "fonts/arial16.fnt");
16. //#else
17. //创建一个文字标签,显示“MainMenu”字符串
18. "MainMenu", "Arial", 20);
19. //#endif
20. //增加一个菜单标签,设定其被按下时的回调函数,用于返回到主界面
21. this, menu_selector(TestScene::MainMenuCallback));
22. //将菜单标签加入创建的菜单中,并设置相应位置。
23. CCMenu* pMenu =CCMenu::create(pMenuItem, NULL);
24. CCSize s = CCDirector::sharedDirector()->getWinSize();
25. pMenu->setPosition( CCPointZero );
26. pMenuItem->setPosition( CCPointMake( s.width - 50, 25) );
27. //将菜单放入场景中。
28. addChild(pMenu, 1);
29. }
30. //菜单标签被按下时的响应函数
31. void TestScene::MainMenuCallback(CCObject* pSender)
32. {
33. //新创建一个场景。
34. CCScene* pScene = CCScene::create();
35. //新创建一个TestController对象
36. new TestController();
37. pLayer->autorelease();
38. //将它放入新创建的场景中并运行。
39. pScene->addChild(pLayer);
40. CCDirector::sharedDirector()->replaceScene(pScene);
41. }
在TestScene中,提供了一个可以被点击的标签MainMenu,从字面意思就知道点击它可以返回主菜单界面,这个主菜单在哪呢?就是TestController。
[cpp] view plain copy
1. #ifndef _CONTROLLER_H_
2. #define _CONTROLLER_H_
3.
4. #include "cocos2d.h"
5.
6. USING_NS_CC;
7.
8. class TestController : public CCLayer
9. {
10. public:
11. //构造
12. TestController();
13. //析构
14. ~TestController();
15. //菜单项响应回调函数
16. void menuCallback(CCObject * pSender);
17. //关闭程序响应回调函数
18. void closeCallback(CCObject * pSender);
19. //按下触点响应函数。
20. virtual void ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent);
21. //按下状态移动触点响应函数。
22. virtual void ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent);
23.
24. private:
25. //接下状态移动触点的开始位置
26. CCPoint m_tBeginPos;
27. //主菜单
28. CCMenu* m_pItemMenu;
29. };
30.
31. #endif
进入Cpp看一下:
[cpp] view plain copy
1. #include "controller.h"
2. #include "testResource.h"
3. #include "tests.h"
4. //菜单项的行间距 ,设40点
5. #define LINE_SPACE 40
6. //创建一个当前触点位置变量,初始化为左下角位置。
7. static CCPoint s_tCurPos = CCPointZero;
8. //创建指定的示例场景
9. static TestScene* CreateTestScene(int nIdx)
10. {
11. //先清空一下显示设备使用的数据
12. CCDirector::sharedDirector()->purgeCachedData();
13.
14. //定义TestScene指针用于接收创建的示例场景
15. TestScene* pScene = NULL;
16. //跟据参数来创建相应的TestScene派生类对象。
17. switch (nIdx)
18. {
19. case TEST_ACTIONS://动画处理
20. new ActionsTestScene(); break;
21. case TEST_TRANSITIONS://场景切换
22. new TransitionsTestScene(); break;
23. case TEST_PROGRESS_ACTIONS://进度动画控制
24. new ProgressActionsTestScene(); break;
25. case TEST_EFFECTS://特效演示
26. new EffectTestScene(); break;
27. case TEST_CLICK_AND_MOVE://拖动演示
28. new ClickAndMoveTestScene(); break;
29. case TEST_ROTATE_WORLD://旋转CCLayer
30. new RotateWorldTestScene(); break;
31. case TEST_PARTICLE://粒子系统
32. new ParticleTestScene(); break;
33. case TEST_EASE_ACTIONS://多样化运动动画
34. new ActionsEaseTestScene(); break;
35. case TEST_MOTION_STREAK://拖尾动画效果
36. new MotionStreakTestScene(); break;
37. case TEST_DRAW_PRIMITIVES://基本图形绘制
38. new DrawPrimitivesTestScene(); break;
39. case TEST_COCOSNODE://结点控制
40. new CocosNodeTestScene(); break;
41. case TEST_TOUCHES://触屏处理
42. new PongScene(); break;
43. case TEST_MENU://菜单处理
44. new MenuTestScene(); break;
45. case TEST_ACTION_MANAGER://动画管理
46. new ActionManagerTestScene(); break;
47. case TEST_LAYER://CCLayer功能展示
48. new LayerTestScene(); break;
49. case TEST_SCENE://CCScene功能展示
50. new SceneTestScene(); break;
51. case TEST_PARALLAX://视角控制
52. new ParallaxTestScene(); break;
53. case TEST_TILE_MAP://基于格子的地图
54. new TileMapTestScene(); break;
55. case TEST_INTERVAL://时间控制
56. new IntervalTestScene(); break;
57. case TEST_CHIPMUNKACCELTOUCH://ChipMunk物理引擎与多点触屏
58. #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
59. new ChipmunkAccelTouchTestScene(); break;
60. #else
61. #ifdef MARMALADEUSECHIPMUNK
62. #if (MARMALADEUSECHIPMUNK == 1)
63. new ChipmunkAccelTouchTestScene();
64. #endif
65. break;
66. #endif
67. #endif
68. case TEST_LABEL://文字标签
69. new AtlasTestScene(); break;
70. case TEST_TEXT_INPUT://输入处理
71. new TextInputTestScene(); break;
72. case TEST_SPRITE://精灵功能展示
73. new SpriteTestScene(); break;
74. case TEST_SCHEDULER://动画的时间调度
75. new SchedulerTestScene(); break;
76. case TEST_RENDERTEXTURE://渲染到纹理
77. new RenderTextureScene(); break;
78. case TEST_TEXTURE2D://纹理功能展示
79. new TextureTestScene(); break;
80. case TEST_BOX2D://Box2D物理引擎展示
81. new Box2DTestScene(); break;
82. case TEST_BOX2DBED: //Box2D物理引擎展示[物体的固定与连接]
83. new Box2dTestBedScene(); break;
84. case TEST_EFFECT_ADVANCE://高级屏幕效果
85. new EffectAdvanceScene(); break;
86. case TEST_ACCELEROMRTER://加速度
87. new AccelerometerTestScene(); break;
88. #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA)
89. case TEST_KEYPAD://键区处理
90. new KeypadTestScene(); break;
91. #endif
92. case TEST_COCOSDENSHION://声效控制
93. new CocosDenshionTestScene(); break;
94. case TEST_PERFORMANCE://性能测试
95. new PerformanceTestScene(); break;
96. case TEST_ZWOPTEX://ZWOPTEX动国
97. new ZwoptexTestScene(); break;
98. #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
99. // bada don't support libcurl
100. #if (CC_TARGET_PLATFORM != CC_PLATFORM_BADA)
101. case TEST_CURL://网络通信基本演示
102. new CurlTestScene(); break;
103. #endif
104. #endif
105. case TEST_USERDEFAULT://用户日志保存示例
106. new UserDefaultTestScene(); break;
107. case TEST_BUGS://BUG示例
108. new BugsTestScene(); break;
109. case TEST_FONTS://字体演示
110. new FontTestScene(); break;
111. case TEST_CURRENT_LANGUAGE://获取当前语言
112. new CurrentLanguageTestScene(); break;
113. #if (CC_TARGET_PLATFORM != CC_PLATFORM_MARMALADE)
114. case TEST_TEXTURECACHE: pScene = new TextureCacheTestScene(); break;
115. #endif
116. case TEST_EXTENSIONS:
117. //更多扩展实例
118. new ExtensionsTestScene();
119. }
120. break;
121. case TEST_SHADER://使用Shader的渲染演示
122. new ShaderTestScene();
123. break;
124. case TEST_MUTITOUCH://多点触屏
125. new MutiTouchTestScene();
126. break;
127. default:
128. break;
129. }
130. //返回创建的场景
131. return pScene;
132. }
133. //构造函数
134. TestController::TestController()
135. : m_tBeginPos(CCPointZero)
136. {
137. // 加入一个关闭菜单按钮
138. this, menu_selector(TestController::closeCallback) );
139. //创建一个菜单放置关闭按钮
140. CCMenu* pMenu =CCMenu::create(pCloseItem, NULL);
141. CCSize s = CCDirector::sharedDirector()->getWinSize();
142. //设置这个菜单位置
143. pMenu->setPosition( CCPointZero );
144. pCloseItem->setPosition(CCPointMake( s.width - 30, s.height - 30));
145.
146. //新建一个测试项菜单,将所有代表测试场景的菜单标签项加入菜单
147. m_pItemMenu = CCMenu::create();
148. //
149. for (int i = 0; i < TESTS_COUNT; ++i)
150. {
151. // #if (CC_TARGET_PLATFORM == CC_PLATFORM_MARMALADE)
152. // CCLabelBMFont* label = CCLabelBMFont::create(g_aTestNames[i].c_str(), "fonts/arial16.fnt");
153. // #else
154. "Arial", 24);
155. // #endif
156. this, menu_selector(TestController::menuCallback));
157. //将代表测试场景的菜单标签加入菜单中,以i+10000的值做为Z值。
158. m_pItemMenu->addChild(pMenuItem, i + 10000);
159. //设置代表测试场景的菜单标签在测试项菜单层的位置
160. pMenuItem->setPosition( CCPointMake( s.width / 2, (s.height - (i + 1) * LINE_SPACE) ));
161. }
162. //设置测试项菜单的大小
163. m_pItemMenu->setContentSize(CCSizeMake(s.width, (TESTS_COUNT + 1) * (LINE_SPACE)));
164. //设置测试项菜单的位置
165. m_pItemMenu->setPosition(s_tCurPos);
166. //将测试项菜单放入当前CCLayer
167. addChild(m_pItemMenu);
168. //设置开启触屏事件响应
169. true);
170. //将关闭按钮项菜单放入当前CCLayer
171. addChild(pMenu, 1);
172.
173. }
174.
175. TestController::~TestController()
176. {
177. }
178. //点击菜单项的事件响应函数
179. void TestController::menuCallback(CCObject * pSender)
180. {
181. // 取得菜单项
182. CCMenuItem* pMenuItem = (CCMenuItem *)(pSender);
183. //取得Z值,减10000算出是第几个菜单项
184. int nIdx = pMenuItem->getZOrder() - 10000;
185.
186. //创建相应的场景
187. TestScene* pScene = CreateTestScene(nIdx);
188. if (pScene)
189. {
190. //运行当前测试场景
191. pScene->runThisTest();
192. //runThisTest中会对其引用计数加1变为2,这里做一次引用计数减1操作,以保证后面再释放场景时可以正常的释放。
193. pScene->release();
194. }
195. }
196. //点击关闭按钮时的响应处理
197. void TestController::closeCallback(CCObject * pSender)
198. {
199. //退出程序
200. CCDirector::sharedDirector()->end();
201. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
202. exit(0);
203. #endif
204. }
205. //触点按下时的响应处理
206. void TestController::ccTouchesBegan(CCSet *pTouches, CCEvent *pEvent)
207. {
208. //获取第一个触点位置
209. CCSetIterator it = pTouches->begin();
210. CCTouch* touch = (CCTouch*)(*it);
211. //将位置保存到变量m_tBeginPos中。
212. m_tBeginPos = touch->getLocation();
213. }
214. //触点
215. void TestController::ccTouchesMoved(CCSet *pTouches, CCEvent *pEvent)
216. {
217. //获取第一个触点位置
218. CCSetIterator it = pTouches->begin();
219. CCTouch* touch = (CCTouch*)(*it);
220. //取得这个位置与上一帧移动的Y值之差,即在纵方向的偏移。
221. CCPoint touchLocation = touch->getLocation();
222. float nMoveY = touchLocation.y - m_tBeginPos.y;
223. //计算菜单在纵方向上也移动相应值后的新位置。
224. CCPoint curPos = m_pItemMenu->getPosition();
225. CCPoint nextPos = ccp(curPos.x, curPos.y + nMoveY);
226. //这里对新位置的有效范围做个限定
227. CCSize winSize = CCDirector::sharedDirector()->getWinSize();
228. if (nextPos.y < 0.0f)
229. {
230. m_pItemMenu->setPosition(CCPointZero);
231. return;
232. }
233.
234. if (nextPos.y > ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height))
235. {
236. m_pItemMenu->setPosition(ccp(0, ((TESTS_COUNT + 1)* LINE_SPACE - winSize.height)));
237. return;
238. }
239. //更新菜单到新位置
240. m_pItemMenu->setPosition(nextPos);
241. //记录当前位置为旧位置。
242. m_tBeginPos = touchLocation;
243. s_tCurPos = nextPos;
244. }
总结:示例框架展示了一个菜单,每个菜单项代表了一个示例工程,菜单项的Z值是递增排列的。点击菜单项响应TestController::menuCallback函数,此函数通过减去Z值基数可以取得菜单项的索引,并通过CreateTestScene(nIdx);来创建出相应的示例场景。本示例框架还演示了如何在纵方向上拖动一个菜单。