手把手教你用cocos2d开发iphone游戏-译文2.4 深入学习HelloWorld 续
来源:互联网 发布:配电箱尺寸计算软件 编辑:程序博客网 时间:2024/05/30 13:43
step 2.AppDelegate
每个 iOS 程序都有一个 AppDelegate 类用于实现 UIApplicationDelegate 协议 (protocol)。这 个命名规则对每个新项目都是一样的:项目名加上 AppDelegate。但是我发现,在cocos2d1.0.0版本之后,凡是新创建的项目都自动省略了HelloWorld或项目的名称,因此,在我们的 HelloWorld 项目中叫做 AppDelegate。当然,如果你是用xcode的标准模板来创建项目,应该还是HelloWorldAppDelegate。
这一点让人恼火,好在不影响实际的项目运行。
AppDelegate 通过在某些时间点从 iOS 接收信息来跟踪程序的状态变化。例如, 你可以用它确认是否有打进来的电话,或者可用的系统内存已经不够用。程序 开始运行后收到的第一个信息是 applicationDidFinishLaun
如果你想学习更多 AppDelegate 相关的方法,怎样使用它们和 iPhone SDK 在什 么时候发送信息,你可以参考苹果官方文档中的 UIApplicationDelegate 协议:http://developer.apple.com/iphone/library/documentation/uikit/reference/UIApplicationDelegate_Protocol
在Xcode中,打开AppDelegate.m文件(译注:有的教程用HelloWorldAppDelegate.m,有的用CCHelloWorldAppDelegate.m,我相信只是版本不同导致文件名不同的问题,里面的内容应该没有神马不同)。
注:既然我们现在讲的是程序启动,我也顺便讲一下程序关闭。你会注意到AppDelegate 中 dealloc 方法存在一个奇怪的地方:这个方法不会被调用!任何在 AppDelegate 的 dealloc 方法中设置的断点都不起作用!这是正常的。当iOS 关闭一个程序时,它只是简单的把内存清空,以加快关闭的速度。这也是为什么 AppDelegate 的 dealloc 方法中的任何代码都不会被运行。你并不需要手动调用 dealloc 方法以“解决这个问题”。如果你确实需要在程序关闭之前在 AppDelegate 中运行代码,你可以在 applicationWillTerminate
代码。如果你的目标 iOS 是 4 或者更高的版本,你应该使用applicationDidEnterBackg
现在让我们进入这个类的代码细节:
切换到applicationDidFinishLaun
如图,在最右侧的No Selection处左键单击,就可以在不同方法间跳转。这个跟xcode3.2.6是不同的,不过熟悉了一样方便。
applicationDidFinishLaun
导演决定让HelloWorld这个场景启动和运行,然后调用场景中已经提前安排好的事情(通常在init这个方法中)
更改动画间隔
动画间隔决定了cocos2d更新屏幕的频率。此设置影响游戏可以达到的最大帧率。不过,动画间隔并不等于多少帧每秒。正相反,它表示的是cocos2d更新屏幕的 频率。这就是为什么它的参数是1.0/60 – 因为1除以60等于0.0167秒,这是在 两次屏幕更新之间的时间间隔。当然,如果你的游戏很复杂,CPU或者GPU将需 要更多的时间来显示下一帧,你的游戏就不可能保证从始至终都达到60帧每秒 的帧率。实际上,保持游戏运行在一个高的帧率上是你的责任。贯穿本书,我 将为你介绍各种提高游戏运行性能的技术。
在某些时候,把帧率设为30帧每秒可能更合适。对于那些很复杂的游戏,它们 的帧率可能在30和60帧每秒之间上下浮动的很厉害,设置一个低一点的帧率会对这样的游戏有所帮助。当你设置了一个低一点的帧率,而且游戏可以稳定的 保持在这个帧率,用户的体验会比使用一个高一些但是不稳定的帧率要好很多。
人的感觉是很复杂的东西。
注:iOS设备不支持超过60帧每秒的帧率,它的屏幕刷新率被锁定在60帧每秒
(Hz)。如果强迫cocos2d以超过60帧每秒的速度进行渲染,在最好的情况下,
可能会不产生任何效果。在最差的情况下,你的帧率可能反而会下降。如果你
想让cocos2d运行在最快的帧率下,把动画间隔设置为1.0/60。
对应代码:
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];
显示帧每秒(FPS) 启用 FPS 显示后,在屏幕的左下角将会显示一个小数字。这是你程序的运行帧率,也就是每秒屏幕会被刷新的帧数。理想状态下,你的游戏应该运行在 60 帧 每秒的帧率,特别是那些动作游戏。有一些游戏,比如大多数的益智游戏,30 帧每秒就可以满足要求。FPS 显示可以帮助你跟踪当前的帧率和任何可能的问 题。
对应代码:
[[CCDirector sharedDirector] setDisplayFPS:YES];
下面是对applicationDidFinishLaun
译注:时间关系,对这里的代码解释还不够详细,后续会把这部分内容再完善一下。
- (void) applicationDidFinishLaun
{
//默认使用kCCDirectorTypeDisplayLi
// kEAGLColorFormatRGBA8
//
//
//
#if GAME_AUTOROTATION == kGameAutorotationUIViewC
#else
#endif
}
//暂停运行游戏,通常是用户锁定iphone屏幕,或是有电话接入时,或任何其它力量导致游戏进入后台
- (void)applicationWillResignAct
}
//继续游戏,当用户解锁屏幕,或电话接听完毕后继续游戏
- (void)applicationDidBecomeActi
}
//当收到内存警报时,从内存中清除当前未使用的精灵纹理
请注意:你所有的图像文件(png,pvr)都被加载成GPU可以理解的opengl es纹理。而精灵则对应着这些纹理图。Cocos2d内置了一个纹理缓存管理器来保持这些纹理图。这样可以极大的加速创建新精灵,并充分利用已有的纹理图。不利的一面是,如果收到内存警报,cocos2d会将当前未使用的纹理图全部从内存中清除。因此,当游戏的场景切换时,有时需要手动释放当前的层和场景。关于这一点,大家争议不断。
- (void)applicationDidReceiveMem
}
//
-(void) applicationDidEnterBackg
}
-(void) applicationWillEnterFore
}
//终止director,将EAGLView从程序窗口UIWindow解除绑定。
- (void)applicationWillTerminate
}
- (void)applicationSignificantTi
}
step 3. HelloWordLayer
HelloWorld类是继承自 CCLayer类的。
因为CCScene只是一个抽象的概念,默认的设置场景的方法是在你的类里面使用 一个静态初始化方法(static initializer)+(id) scene。此方法会生成一 个CCScene对象,并且将HelloWorld的对象添加到场景节点中。几乎在任何情况 下,CCScene都是在这里创建和使用的。
好吧,既然要深入了解,让我们看看scene这个类方法究竟干了些什么。
+(id) scene {
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node]; // 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node]; // add layer as a child to scene
[scene addChild: layer]; // return the scene
return scene;}
第一行是通过调用[CCScene node]来创建一个CCScene的实例化对象。如果你看不明白node是啥意思,让哥来告诉你,其实这行代码等同于[[[CCScene alloc ]init]autorelease]。那么,哥咋知道node的意思呢?狠简单,只要右键单击node,然后选择jump to definition,好吧,这下你无敌了。
首先,CCScene类的静态初始化方法+(id) node生成一个CCScene对象。接下来, 同样的+(id) node方法生成了HelloWorld节点,并被添加到场景中。然后场景被返回给调用者。
译注:
原来如此,[CCScene node]就是初始化一个对象而已。且慢,苹果官方的开发者文档不是说尽量不要使用自动释放对象吗?哎,虽然听苹果的话有好果果吃,但是太听话了就未免过于迂腐。Cocos2d的内存管理机制其实是很完善的,如果你非要用官方的规定来自己手动管理每一个场景,层,精灵等节点的内存,那么好吧,你会崩溃,最后游戏也会不知道神马原因在哪里就突然崩溃了。
如果不信,你大可以自己去尝试。
对于这一点,不同的教程,不同的开发者,苹果官方有不同的看法,大家自己选择何去何从吧。
以下是官方的内存管理指南:
http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/MemoryMgmt
/MemoryMgmt.html
提示:
想知道每个方法的具体定义和调用方式不?按住键盘上的Option,然后鼠标左键单击方法或消息的名称。
此外,对于一个未知的方法,还可以右键单击,然后选择Jump to Definition。
相信我,这一点对于新手学习非常重要!!!
接下来看看-(id)init方法。
// on "init" you need to initialize your instance
-(id) init
{
译注:该语句可以改成:
CGSize size = [CCDirector sharedDirector].winSize;
这样的写法无疑很合其它编程语言转移过来的兄弟胃口
//生成并初始化精灵对象
//将精灵放在屏幕中央
//将精灵作为子节点添加到场景层中
//说明一个moveAction动作,在15秒内移动到屏幕的左侧外,细节后面再解释
//太空货船执行这个动作
}
你可能会注意到一个有些奇怪的地 方:self = [super init]这个调用中,发送给super对象的init信息所返回的 值被赋给了self。如果你有C++的编程经验,你可能会对此很不理解。不需要沮丧!这是因为Objective-C必须手动调用super类的init方法。不存在对父类的 自动调用。而且我们必须把[super init]的返回值赋给self,因为我们有可能 得到一个空值(nil):
如果你很介意上述[super init]的写法,以下是另一种写法。它的作用和上面 的写法完全一样。
-(id) init { self = [super init];
}
if (self != nil) { //在此添加init方法的代码
} return self;
小技巧:如何修改cocos2d所开发游戏的默认屏幕方向
在RootViewController.m文件里面,修改如下代码
#elif GAME_AUTOROTATION == kGameAutorotationUIViewC
红色字体的就是可以更改的地方
请注意,在applicationDidFinishLaun
让HelloWorld更好玩一点(这部分内容先不补充了,后面翻完了回头再完善)
挑战:
cocos2d官方所提供的模板无疑是非常宝贵的资源,建议开发者要多尝试一下。
- 手把手教你用cocos2d开发iphone游戏-译文2.4 深入学习HelloWorld 续
- 手把手教你用cocos2d开发iphone游戏-译文2.3 深入学习HelloWorld
- 手把手教你用cocos2d开发iphone游戏-译文2.2 初探HelloWorld
- 手把手教你用cocos2d开发iphone游戏-译文1
- 译文1 手把手教你用cocos2d开发iphone游戏
- 译文2 手把手教你用cocos2d开发iphone游戏-
- 译文3 手把手教你用cocos2d开发iphone游戏
- 译文4手把手教你用cocos2d开发iphone游戏
- 手把手教你用cocos2d开发iphone游戏-译文2.1 第一部分下载安装cocos2d
- 深入理解iPhone委托模式兼谈iPhone生命周期(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone数据持久化(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone静态库(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone静态库(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone屏幕双缓冲技术(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone静态库(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone数据持久化(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone数据持久化(手把手教你iphone开发 - 基础篇)
- 深入理解iPhone数据持久化(手把手教你iphone开发 - 基础篇)
- C#将Enum枚举映射到文本字符串
- zoj 1196 Fast Food
- 每天学习10句英语-第四天
- 如何彻底卸载删除MySQL 【MYSQL】
- 一个有趣的题目—linux中的fork函数分析
- 手把手教你用cocos2d开发iphone游戏-译文2.4 深入学习HelloWorld 续
- shell 将字符串分割成数组
- 关闭服务端连接
- 每天学习10句英语-第五天
- qt读写XML资料[DOM方式]
- 将List集合中的map对象转为List<对象>形式--封装类
- MFC消息机制逆向追踪
- 使用Stl而没有用到命名空间的错误
- Java 理论与实践: 线程池与工作队列