三、第一个cocos2d程序的代码分析
转自MJ老师:http://blog.csdn.net/q199109106q/article/details/8591706
在第一讲中已经新建了第一个cocos2d程序,运行效果如下: 在这讲中我们来分析下里面的代码,了解cocos2d的工作原理,看看屏幕上的这个"Hello World"是如何显示出来的。 这是HelloWorld项目的代码结构:
下面,我们开始分析项目中的这些源文件: 从程序的入口点开始
|
kCCDirectorTypeNSTimer kCCDirectorTypeDefault | 最慢 |
kCCDirectorTypeMainLoop | 比NSTimer快,但是与UIKit视图存在兼容性问题 |
kCCDirectorTypeThreadMainLoop | 比NSTimer快,但是与UIKit视图存在兼容性问题 |
kCCDirectorTypeDisplayLink | 最快,最实用,但iOS版本至少是3.1 |
3.设置屏幕方向
通过CCDirector来设置屏幕方向
- //设置屏幕方向
- ifGAME_AUTOROTATION==kGameAutorotationUIViewController
- //如果是使用UIViewController来实现旋转,就设置竖屏
- [directorsetDeviceOrientation:kCCDeviceOrientationPortrait];
- else
- //其他情况,就设置横屏
- [directorsetDeviceOrientation:kCCDeviceOrientationLandscapeLeft];
- #endif
下面列出设备支持的所有方向:
kCCDeviceOrientationPortrait | |
kCCDeviceOrientationPortraitUpsideDown | |
kCCDeviceOrientationLandscapeLeft | |
kCCDeviceOrientationLandscapeRight |
4.设置游戏帧率
大家都知道,游戏界面上的内容是需要经常刷新的,比如一个子弹打出去,需要经常刷新子弹的位置。刷新速度就取决于游戏帧率。
- [directorsetAnimationInterval:60];
注意:由于设备的限制,在iOS设备上的帧率不能大于60fps。如果强迫cocos2d以大于60fps的帧率进行渲染,很有可能会反而使帧率降低。因此,要想达到最快的渲染速度,使用60fps的帧率即可。
5.显示游戏帧率
- [directorsetDisplayFPS:YES];
cocos2d会隔一段时间就更新这个数值,通过修改ccConfig.h的CC_DIRECTOR_FPS_INTERVAL值可以调整刷新数值的时间间隔,默认是0.1,即1秒钟更新10次。ccConfig.h在项目的libs/cocos2d文件夹中。
- #ifndefCC_DIRECTOR_FPS_INTERVAL
- #defineCC_DIRECTOR_FPS_INTERVAL(0.1f)
- #endif
6.设置游戏的第一个场景
- [[CCDirectorsharedDirector]runWithScene:[HelloWorldLayerscene]];
因此,需要搞清楚屏幕上显示的"Hello World"是怎么弄出来的,还得查看HelloWorldLayer这个类
7.在发出内存警告时释放资源
- void)applicationDidReceiveMemoryWarning:(UIApplication*)application{
- [[CCDirectorsharedDirector]purgeCachedData];
- }
HelloWorldLayer解读
打开HelloWorldLayer.h,可以发现HelloWorldLayer继承了CCLayer,意为图层
- @interfaceHelloWorldLayer:CCLayer
- }
- //returnsaCCScenethatcontainstheHelloWorldLayerastheonlychild
- +(CCScene*)scene;
- @end
那之前看到的场景(CCScene)和图层(CCLayer)究竟有什么联系呢?
下面我先详细阐述场景(CCScene)和图层(CCLayer)之间的关系:
一个游戏里面可能有很多个场景,比如闯关游戏,可以一个关卡就是一个场景,一个游戏设置界面也可以是一个场景。一个场景里面又可以包含多个图层。
拿捕鱼达人来说,下面列出捕鱼达人中的4个场景:
场景1 | |
场景2 |
|
场景3 | |
场景4 |
|
可以看出,不同的业务逻辑就放在不同的场景中。但是,如果一个场景过于复杂,场景里面又可以分出多个图层(CCLayer)。
比如场景4中的捕鱼界面,根据图层的功能,大致可以分为3个图层:
1> 底部的Background Layer是背景层,用来显示背景图片
2> 中间的Game Layer是游戏层,用来显示游戏中的精灵(CCSprite,可以用来表示游戏中的人物、道具等),这里的鱼就是精灵
3> 顶部的UI DOM Menu是菜单层,用来显示一些菜单按钮、控制按钮
再查看HelloWorldLayer.m中scene方法的实现
- +(CCScene*)scene
- //创建一个场景对象
- CCScene*scene=[CCScenenode];
- //创建一个图层对象
- HelloWorldLayer*layer=[HelloWorldLayernode];
- //添加图层到场景中
- [sceneaddChild:layer];
- //返回场景
- returnscene;
- }
这里使用[CCScene node]创建了一个CCScene对象,使用[HelloWorldLayer node]创建了一个HelloWorldLayer对象。
最后通过[scene addChild: layer]将图层layer添加到场景scene中,可以看出layer是scene的一个子节点。实际上addChild:方法也是属于CCNode的,可以看出每个CCNode都有自己的子节点。
- -(id)init
- //alwayscall"super"init
- //Applerecommendstore-assign"self"withthe"super"returnvalue
- if((self=[superinit])){
- //createandinitializeaLabel
- CCLabelTTF*label=[CCLabelTTFlabelWithString:@"HelloWorld"fontName:@"MarkerFelt"fontSize:64];
- //askdirectorthethewindowsize
- CGSizesize=[[CCDirectorsharedDirector]winSize];
- //positionthelabelonthecenterofthescreen
- label.position=ccp(size.width/2,size.height/2);
- //addthelabelasachildtothisLayer
- [selfaddChild:label];
- }
- returnself;
- }
- CCLabelTTF*label=[CCLabelTTFlabelWithString:@"HelloWorld"fontName:@"MarkerFelt"fontSize:64];
- CGSizesize=[[CCDirectorsharedDirector]winSize];
- label.position=ccp(size.width/2);
- #defineccp(__X__,__Y__)CGPointMake(__X__,__Y__)
- [selfaddChild:label];
就这样,"Hello World"就显示到我们的屏幕上了
分析可得,我们这个游戏里面存在着3个节点:
CCScene里面有个CCLayer,CClayer里面有个CCLabelTTF
总结
说了这么多内容,最后做个大总结:
1.要想利用cocos2d在屏幕上显示点东西,就必须使用CCDirector运行一个场景(CCScene),比如
- [[CCDirectorsharedDirector]runWithScene:[HelloWorldLayerscene]];
2.场景(CCScene)可以添加多个图层(CCLayer),每个图层又可以添加其他子节点,比如精灵(CCSprite)
3.cocos2d会利用OpenGL将场景(CCScene)中的所有内容渲染到UIKit视图上(这里用的是EAGLView),EAGLView被添加到UIWindow中,最终显示在屏幕上
4.大部分情况下,都是直接面向cocos2d进行开发,即直接用cocos2d的CCSprite、CCLayer、CCScene等类进行开发,不需要关心OpenGL与UIKit之间的转换
5.cocos2d的基本元素是节点(CCNode),屏幕上的任何东西都可以称之为节点,像我们常用的CCSprite、CCLayer、CCScene,都是CCNode的子类,因此,它们都是节点。一个节点又可以包含多个子节点
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!