AppDelegate.m
代码------------------------------------------------------------------------------------------------------------------------------------------------
- (void) removeStartupFlicker
代码------------------------------------------------------------------------------------------------------------------------------------------------
//removeStartupFlicker这个方法是专门用来去除闪烁的,只要打开注释,把//CCSprite *sprite = [CCSprite spriteWithFile:@"Default.png"];
//替换成自己定义的Default名字就可以了。这样我们可以在程序开始显示Default这个图片,以实现Default的淡出效果,以及与logo的完美切换。
代码------------------------------------------------------------------------------------------------------------------------------------------------
#if GAME_AUTOROTATION == kGameAutorotationUIViewController
代码------------------------------------------------------------------------------------------------------------------------------------------------
//Cocos2D横竖屏设置
// 项目设计的时候首先决定有无需求做自动旋转,没有的话就用 kGameAutoroationNone
// 有的话再决定从 kGameAutorotationUIViewController 和 kGameAutorotationCCDirector 里面选一个。
// 后面二者的区别:
// CCDirector 是那种直来直往的,屏幕一翻转它会一步到位将画面翻转过来。
// UIViewController 则不一样,旋转的时候他会有个过渡的旋转效果,个人感觉比 CCDirector 那种的体验要好。
代码------------------------------------------------------------------------------------------------------------------------------------------------
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
代码------------------------------------------------------------------------------------------------------------------------------------------------
// UIScreen类代表了屏幕,通过这个类我们可以获取一些想要的东东。// CGrect screenBounds = [ [UIScreen mainScreen]bounds];//返回的是带有状态栏的Rect
// CGRect viewBounds = [ [UIScreen mainScreen]applicationFrame];//不包含状态栏的Rect
// screenBounds 与 viewBounds 均是相对于设备屏幕来说的
// 所以 screenBounds.origin.x== 0.0 ; screenBounds.oringin.y = 0.0;
// screenBounds.size.width == 320; screenBounds.size.height == 480(或者其他分辨率有所差异)
// 所以 screenBounds.origin.x== 0.0 ; screenBounds.oringin.y = 20.0;(因为状态栏的高度是20像素) screenBounds.size.width == 320; screenBounds.size.height == 480
// 取得StatusBar的位置和大小
// [self.view addSubview:theToolbar];
代码------------------------------------------------------------------------------------------------------------------------------------------------
if( ! [CCDirector setDirectorType:kCCDirectorTypeDisplayLink] )
[CCDirector setDirectorType:kCCDirectorTypeDefault];
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 判断你的设备是否支持CCDirectorTypeDisplayLink模式,如果不支持就设置为CCDirectorTypeDefault类型。// CCDirectorTypeDisplayLink:利用iPhoneOS 3.1新特性,提供高于NSTimer的执行效率,保持与UIKit的兼容性。默认的就是NSTimer的执行效率。
// 这几个 Type 的区别主要和 Director 的一个重要功能有关,就是对 mainLoop: 的调用有关。
// 整个 Cocos2d 的渲染都是源自 mainLoop:,每一帧渲染就是一次 mainLoop: 的调用。
// 四个不同的 Director 就是四种不同调用 mainLoop: 的方式:
//# kCCDirectorTypeNSTimer,使用 API 设定定时器,定时器到了之后就调用 mainLoop:
//# kCCDirectorTypeMainLoop,就是cocos2d自己用代码写的一个死循环,每次循环调用 mainLoop: 一次
//# kCCDirectorTypeThreadMainLoop,就是cocos2d单独创建一个线程,在那个线程里面写死循环
//# kCCDirectorTypeDisplayLink,就是和设备的刷新率同步,设备显示每刷新一次,就调用 mainLoop: 一次
代码------------------------------------------------------------------------------------------------------------------------------------------------
CCDirector *director = [CCDirector sharedDirector];
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 导演类也是一个单例,有两大作用,一是设置主窗口的显示属性(比如垂直或水平、是否显示FPS),二是管理、显示场景。// 场景是树的根节点,一个游戏可以同时存在多个树,但被激活的只能有一个,导演类的实现方法是:将所有树的根节点(即场景对象)保存在一个堆栈中(array),最后进栈的就是当前激活的场景,当需要切换场景时,导演通过进栈、出栈或替换的方式实现。
// 常用方法:
// +( CCDirector) shared CCDirector
// 获取单例。
// -(void) runWithScene: (CCScene*)scene
// 将场景对象压入栈中,并激活(此时不能有已经激活的场景,因此该方法常用于刚进游戏时)。
// -(void) replaceScene: (CCScene*)scene
// 替换当前激活的场景,同时将旧场景从堆栈中删除,新场景压入堆栈。
// -(void) pushScene: (CCScene*) scene
// 添加新的场景进栈,并将其激活。
// -(void) popScene
// 当前激活的场景出栈,激活上一个场景。
// -(void) pause
// 暂停。
// -(void) resume
// 恢复。
// CCDirector是singleton模式的共享的对象。它知道当前哪个scene是激活。 CCDirector以stack的方式处理scenes的调用(当另一个scene进入的时候,暂停当前的scene,完成之后再返回原来的 scene),CCDirector 负责更换CCScene,在 CCLayer 被push的时候,更换或结束当前的scene。另外:CCDirector 负责初始化OpenGL ES。
// 作用:
// 1.访问和改变场景
// 2.访问cocos2d的配置细节
// 3.访问视图,(openGL, UIView, UIWindow)
// 4.暂停,恢复和结束游戏
// 5.在UIKit和OpenGL之间转换坐标
// 常用的方法:
// 1.主程序启劢,显示第一个场景的方法:(void) runWithScene:(Scene*) scene;
// 2. 挂起当前当前正在运行的场景并压栈到代执行场景队列。将传入场景设置为当前执行场景:(void) pushScene:(Scene*) scene;
// 3. 执行代执行场景队列中的最后一个场景,当前场景被释放:(void) popScene;当代执行队列中没有代执行场景时,系统自劢退出,调用 end 方法。
// 4. 直接用一个场景取代当前执行场景,释放当前场景:(void) replaceScene:(Scene*) scene;是经常实用的函数
// 5.结束场景运行:(void) end;
// 6.暂停场景运行:(void) pause;画面还存在,时间任务停止。
// 7.恢复场景运行:-(void) resume;
// CCDirector。在整个游戏中一般只有一个导演。在游戏开始时,初始化CCDirector,游戏结束时,销毁它。CCDirector提供了管理场景的方法,如runWithScene、drawScene、pushScene和replaceScene等,通过这些API可以实现在各个场景之间切换,CCDirector也可以设置或者获取一些系统信息,如调整OpenGL的相关设置,获取屏幕的大小等。
// cocos2d-x除了提供CCDirector外,还提供了CCDisplayLinkDirector。CCDisplayLinkDirector是一个可以自动刷新的CCDirector。CCDisplayLinkDirector继承自CCDirector,CCDirector继承自CCObject。
// CCDirector主要负责当前窗口的内容,并且负责场景的切换和管理,它同时还还负责:
// 1. OpenGL中上下文的初始化(当然这在XNA中很多东西没有了)
// 2. 设置投影方式,默认为3D透视投影
// 3. 设置屏幕方向
// 4. 它是一个单实例
// 5. 设置着色器一些通用参数
// 1. 对于投影方式,cocos2d同时支持2D投影和3D投影,默认为3D投影,2D的情况下采用的是正投影。但是cocos2d大部分的功能需要3D的方式才能实现,所以你不应该随便切换为2D,除非你确保2D的方式能实现接下来要使用的功能。cocos2d中的2D投影主要是用来处理和2D相关的绘制,并且出于性能考虑,在某些特殊的情况下用2D来绘制,以后会讲到。
// 2. 对于XNA中basicEffect的一些通用默认参数的设置,比如TextureEnabled可以放在CCDirector来做,目前全部放到Draw方法中设置,这个以后放在优化之列。
// 但是除此之外,CCDirector还有许多辅助的功能,这些是注释当中没有的,而开发中会遇到的,这里我在列举一下:
// 1. 显示和设置FPS
// 2. 修改窗口大小,绘制缩放比例
// 3. OpenGL坐标和屏幕位置之间的转化,也就是基于左上角为原点坐标系中的点,和左下角为原点的坐标系中的点的坐标转换,这个比如在XNA中接受的Touch事件中的点是左上角为原点的坐标系,在处理的时候需要转换为左下角为原点的坐标系
// 4. 获取和设置窗口尺寸
// 5. 一共运行了多少帧
// 6. 设置AlphaBlending,深度测试等
// 当然,CCDirector最重要的功能是场景管理,
// CCDirector 作用
// 1 设置主窗口显示的属性
// 设定Director对象与当前窗口的关系,便于director操作主窗口
// 设置主窗口方向
// 是否显示fps
// 设定每秒帧数
// 设定主窗口显示图像的调色盘位宽
// 管理,显示场景
// 1当前正在显示的场景Scene *runningScene_
// 2 下一个将要显示的场景 Scene *nextScene;
// 3 等待执行场景队列NSMutableArray *scenesStack;
// Director 对象管理场景的方法
// 1 显示第一个场景
// (void)runWithScene:(Scene *)scene;
// 2挂起当前正在运行的场景并压栈到带执行场景队列,将传入场景设置为当前执行场景
// (void)pushScene:(Scene *)scene;
// 3执行代执行场景队列中最后一个场景,当前场景被释放
// (void)popScence
// 当带执行队列中没有代执行场景时,系统自动退出,调用end方法
// 4 直接用一个场景取代当前执行场景,释放当前场景
// (void)replacesScene:(Scene *)scene 这个函数经常使用
// 5结束场景运行 (void)end;
// 6停止场景运行 (void)pause
// 7恢复运行-(void) resume
代码------------------------------------------------------------------------------------------------------------------------------------------------
viewController = [[RootViewController alloc] initWithNibName:nil bundle:nil];
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 创建RootViewController这个视图控制器的实例。使用alloc方法创建一个视图控制器,然后用initWithNibName:bundle:方法对其进行初始化。init方法先指定控制器应加载的nib文件,然后指定在哪个程序包中可找到该文件。程序包是文件系统某个位置的抽象,该位置存放了应用程序将会用到的代码和资源。
// 使用属性的存取方法,将创建好的视图控制器实例设置为viewController属性变量的值
// 根据内存管理规则释放视图控制器
// 视图控制器用来配置和管理在应用程序中看到的视图,每一个视图也对应有一个视图控制器来管理。窗体(window)有一个根视图控制器——这个视图控制器负责配置当窗体显示时最先显示的视图。要让你的视图控制器的内容显示在窗体中,需要去设置窗体的根视图控制器为你的视图控制器。
代码------------------------------------------------------------------------------------------------------------------------------------------------
viewController.wantsFullScreenLayout = YES;/
代码------------------------------------------------------------------------------------------------------------------------------------------------
;// viewController的一个属性,这个属性默认值是NO,如果设置为YES的话,如果statusbar,navigationbar, toolbar是半透明的话,viewController的view就会缩放延伸到它们下面,但注意一点儿tabBar不在范围内,即无论该属性是否为YES,view都不会覆盖到tabbar的下方
代码------------------------------------------------------------------------------------------------------------------------------------------------
EAGLView *glView = [EAGLView viewWithFrame:[window bounds]// EAGLView 派生类 UIView, 苹果公司用它来实现 OpenGL 输出支持,以支持OpenGL ES 编程:
pixelFormat:kEAGLColorFormatRGB565 // kEAGLColorFormatRGBA8// 这个参数代表像素格式
depthFormat:0 // GL_DEPTH_COMPONENT16_OES// 这个参数代表浓度深度缓冲是一个与你的渲染目标(render target)相同大小的缓冲,这个缓冲记录每个像素的深度
];
代码------------------------------------------------------------------------------------------------------------------------------------------------
[director setOpenGLView:glView];//绑定到OpelGL
代码------------------------------------------------------------------------------------------------------------------------------------------------
#if GAME_AUTOROTATION == kGameAutorotationUIViewController//设置设备的方向
[director setDeviceOrientation:kCCDeviceOrientationPortrait];//竖屏
#else
[director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft];//横屏
#endif
代码------------------------------------------------------------------------------------------------------------------------------------------------
// UIDeviceOrientationFaceUp朝上平躺
// UIDeviceOrientationFaceDown朝下平躺
// UIDeviceOrientationLandscapeLeft向左橫置
// UIDeviceOrientationLandscapeRight向右橫置
// UIDeviceOrientationPortrait直立
// UIDeviceOrientationPortraitUpsideDown直立,上下顛倒
// UIDeviceOrientationUnknown未知方向
//return (interfaceOrientation == UIInterfaceOrientationLandscapeLeft); // 只支持向左横向, YES 表示支持所有方向
代码------------------------------------------------------------------------------------------------------------------------------------------------
[director setAnimationInterval:1.0/60];
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 动作间隔决定了cocos2d刷新屏幕的频率,它关乎游戏可以获得的最大帧率。但动作间隔并不等同于每秒刷新多少帧。相反,它表示的是cocos2d刷新一帧所需要的时间。在上面的代码中,动作间隔的参数为1.0/60,这就是cocos2d对屏幕进行连续两次刷新之间的时间间隔。
// 很多情况下,最好把帧率设置为30fps。这对复杂游戏很有帮助,因为这样做可以避免由于帧率无法达到60fps,而在游戏过程中发生30fps到60fps间的大幅波动。在这种情况下,最好把帧率设为可能达到的最低帧率,因为较低但是稳定的帧率可以保证游戏的流畅运行,而平均帧率较高但是帧率可能发生大幅波动的游戏会降低玩家的用户体验。
// 注意:在iOS设备上不能以高于60fps的帧率进行渲染,因为设备的屏幕刷新率被锁定为最高60fps。如果强迫cocos2d以高于60fps的帧率进行渲染,那么在最好情况下,cocos2d会以60fps的帧率进行渲染;而在最坏情况下,它的帧率反而会下降。所以,如果想让cocos2d以最快速度进行渲染,应把动作间隔参数设为1.0/60。
[director setDisplayFPS:YES];//显示每秒帧数//使能“Display FPS”后屏幕的左下角会显示一个小数字。这个是你的帧速率,理想状况是你的游戏在任何时候都能跑在60fps上。这个FPS显示能帮助你跟踪帧速率和游戏中出现的任何打嗝和结巴状况。启动帧率显示功能以后,在屏幕的左下角会出现一个小小的数字,这就是应用程序的帧率,或者硕士每秒刷新的帧数。
// 注意:如果需要调整显示帧率的反应速度,可以在ccConfig.h文件中修改CC_DIRECTOR_FPS_INTERVAL代码行。该文件位于cocos2d Sources/cocos2d中。该值默认为0.1,即在默认情况下,表示帧率的数字会在每秒被刷新10次。如果增大该值,那么小数字就会被刷新得更慢,虽然这个变化不明显,但还是存在的。
代码------------------------------------------------------------------------------------------------------------------------------------------------
[viewController setView:glView];//设定viewController的view为glView。
[window addSubview: viewController.view];//addSubview 是将view加到所有层的最顶层
代码------------------------------------------------------------------------------------------------------------------------------------------------
// //方法一,新方法
// self.window.rootViewController = self.tabBarController;
// [self.window makeKeyAndVisible];
//
// //方法二,旧方法
// [_window addSubview:self.tabBarController.view];
// [_window makeKeyAndVisible];
// 4.0之前用addsubview 之后用RootViewController
代码------------------------------------------------------------------------------------------------------------------------------------------------
[window makeKeyAndVisible];//makeKeyAndVisible作用被使用对象的主窗口显示到屏幕的最前端。
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
代码------------------------------------------------------------------------------------------------------------------------------------------------
//更改默认的纹理像素格式,设置渲染格式位32位RGB,纹理像素格式的改变会影响后面加载的所有纹理。因此,如果你想后面加载纹理使用不同的像素格式的话,必须再调用此方法,并且重新设置一遍像素格式,像素格式与图片本身的像素格式不匹配的话,就会导致显示严重失真。比如颜色不对,或者透明度不对等
// 有哪些比较有用的纹理像素格式呢?
// generate 32-bit textures: kCCTexture2DPixelFormat_RGBA8888 (default)
// generate 16-bit textures: kCCTexture2DPixelFormat_RGBA4444
// generate 16-bit textures: kCCTexture2DPixelFormat_RGB5A1
// generate 16-bit textures: kCCTexture2DPixelFormat_RGB565 (no alpha)
// RGBA8888是默认的格式。对于16位的纹理来说,使用RGB565可以获得最佳颜色质量,因为16位全部用来显示颜色:总共有65536总颜色值。但是,这里有个缺点,除非图片是矩形的,并且没有透明像素。所以RBG565格式比较适合背景图片和一些矩形的用户控件。
// RBG5A1格式使用一位颜色来表示alpha通道,因此图片可以拥有透明区域。只是,1位似乎有点不够用,它只能表示32768种可用颜色值。而且图片要么只能全部是透明像素,或者全部是不透明的像素。因为一位的alpha通道的缘故,所以没有中间值。但是你可以使用fade in/out动作来改变纹理的opacity属性。
// 如果你的图片包含有半透明的区域,那么RBGA4444格式很有用。它允许每一个像素值有127个alpha值,因此透明效率与RGBA8888格式的纹理差别不是很大。但是,由于颜色总量减少至4096,所以,RBGA4444是16位图片格式里面颜色质量最差的。
// 现在,你可以得到16位纹理的不足之处了:它由于颜色总量的减少,有一些图片显示起来可能会失真,而且可能会产生“梯度”。
代码------------------------------------------------------------------------------------------------------------------------------------------------
[self removeStartupFlicker];//移除闪屏,即一开始的那个coco2d Logo标志的屏幕
[[CCDirector sharedDirector] runWithScene: [HelloWorldLayer scene]];//将场景入栈,并激活。(只适用于整个App的第一个CCScene)
代码------------------------------------------------------------------------------------------------------------------------------------------------
// CCScene的4个基本方法:runWithScene(运行画面),replaceScene(替换场景 例如从主菜单进入游戏界面),
// pushScene(暂停界面), popScene(从暂停的界面还原到游戏界面)CCDirector 负责scenes之间的前进或后退
代码------------------------------------------------------------------------------------------------------------------------------------------------
- (void)applicationWillResignActive:(UIApplication *)application {
[[CCDirector sharedDirector] pause];//游戏暂停
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 当有电话进来或者锁屏,这时你的应用程会挂起,在这时,UIApplicationDelegate委托会收到通知,调用 applicationWillResignActive 方法,你可以重写这个方法,做挂起前的工作,比如关闭网络,保存数据。
代码------------------------------------------------------------------------------------------------------------------------------------------------
- (void)applicationDidBecomeActive:(UIApplication *)application {
[[CCDirector sharedDirector] resume];//游戏复原
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 当程序复原时,另一个名为 applicationDidBecomeActive 委托方法会被调用,在此你可以通过之前挂起前保存的数据来恢复你的应用程序:
// 注意:应用程序在启动时,在调用了 applicationDidFinishLaunching 方法之后也会调用 applicationDidBecomeActive 方法,所以你要确保你的代码能够分清复原与启动,避免出现逻辑上的bug。
代码------------------------------------------------------------------------------------------------------------------------------------------------
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
[[CCDirector sharedDirector] purgeCachedData];
代码------------------------------------------------------------------------------------------------------------------------------------------------
//清除所有缓存数据,设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,在终止前会执行这个方法,通常可以在这里进行内存清理工作防止程序被终止
代码------------------------------------------------------------------------------------------------------------------------------------------------
-(void) applicationDidEnterBackground:(UIApplication*)application {
[[CCDirector sharedDirector] stopAnimation];
代码------------------------------------------------------------------------------------------------------------------------------------------------
//当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可
代码------------------------------------------------------------------------------------------------------------------------------------------------
-(void) applicationWillEnterForeground:(UIApplication*)application {
[[CCDirector sharedDirector] startAnimation];
代码------------------------------------------------------------------------------------------------------------------------------------------------
//当程序从后台将要重新回到前台时候调用
代码------------------------------------------------------------------------------------------------------------------------------------------------
- (void)applicationWillTerminate:(UIApplication *)application {
代码------------------------------------------------------------------------------------------------------------------------------------------------
// 当用户按下按钮,或者关机,程序都会被终止。当一个程序将要正常终止时会调用 applicationWillTerminate方法。但是如果长主按钮强制退出,则不会调用该方法。这个方法该执行剩下的清理工作,比如所有的连接都能正常关闭,并在程序退出前执行任何其他的必要的工作,这个需要要设置UIApplicationExitsOnSuspend的键值。
代码------------------------------------------------------------------------------------------------------------------------------------------------
- (void)applicationSignificantTimeChange:(UIApplication *)application {
[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
代码------------------------------------------------------------------------------------------------------------------------------------------------
//当系统时间发生改变时执行
//设置下次增量时间是否为零