这一节将向游戏开发者介绍HelloWorld项目的目录结构,以及各个部分是如何协同工做的。经过本节的学习,你会对各个部分之间的联系有个大体的了解。html
图13.22显示了HelloWorld项目的项目导航面板。node
图13.22
ios
cocos2d项目引用两类不一样的文件:源码文件和资源文件(包括图像文件、声音文件和属性文件等)。Default.png文件是在iOS加载应用程序时显示的图像,Icon.png是应用程序部署在设备上的图标。不一样设备上可能使用这些文件类型的不一样版本。例如,Retina 设备上会加载带有@2x后缀的图像文件。关于应用程序图标、启动图像等图像尺寸和格式的完整列表,能够参考苹果公司的开发者文档中的Custom Icon and Image Creation Guidelines,具体网址是:http://developer.apple.com/library/ios/ documentation/userexperience/conceptual/ mobilehig/IconsImages/IconsImages.html#//apple_ref/doc/uid/TP40006556-CH14-SW1。app
fps_p_w_picpaths.png文件用于显示帧率,是不容许删除或修改的。框架
Info.plist文件包含了一些与项目相关的配置信息,同时也能够在这个文件中修改一些重要的设置,如项目图标、支持设备的方向等。ide
任何一个使用Xcode开发的应用程序或游戏都是从main.m开始的。在导航区域的“Supporting Files”组下面能够找到main.m文件。main.m的代码以下。函数
程序清单:codes/13/13.3/HelloWorld/HelloWorld/main.m学习
#import <UIKit/UIKit.h>动画
int main(int argc,char *argv[]) {ui
@autoreleasepool {
int retVal = UIApplicationMain(argc,argv,nil,@"AppController");
return retVal;
}
}
简单来讲,main函数建立了@autoreleasepool(自动释放池),而后调用UIApplicationMain来启动程序。其中,AppController是实现UIApplicationDelegate协议的类,AppController类的实现包含在AppDelegate文件中。在启用了ARC的cocos2d应用程序中,Autorelease Pool(自动释放池)能够确保内存的对象最终被释放。
该组中的另外一个文件Prefix.pch是预编译头文件,用于加快编译速度。pch表示Pre-Compiled Header,游戏开发者应该把不常变化的框架(Frameworks)头文件添加到该文件中。这样作可使框架的代码提早被编译,并对全部类可见。
不过,这样作要注意一个问题:若是pch前缀头文件中的一个头文件发生了变化,项目中的全部代码都将会从新编译。因此,pch前缀头文件中只应该添加那些极少或者历来都不发生变化的头文件。
游戏开发者能够将cocos2d.h头文件添加到pch前缀头文件中,由于它几乎不会改变。并且,一开始就将cocos2d.h添加到预编译头文件中是一个很是好的习惯,这样在其余源文件中就没必要再写“#import "cocos2d.h"”了。在预编译头文件中加入cocos2d.h,代码以下。
程序清单:codes/13/13.3/HelloWorld/HelloWorld/Prefix.pch
#import <Availability.h>
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "cocos2d.h"
#endif
每一个iOS程序都有一个AppDelegate类,用于实现UIApplicationDelegate协议。AppDelegate实现的方法用于处理iOS应用程序的状态改变。例如,能够经过它来处理用户来电或者系统内存不足时程序须要采起的措施。在查看AppDelegate方法的具体实现代码前,先要了解AppDelegate.h中的类定义。在AppDelegate.h中定义了AppController这个类,它直接继承自NSObject类,而且遵循UIApplicationDelegate和CCDirectorDelegate两个协议。
程序加载完成后,当即执行的方法就是applicationDidFinishLaunchingWithOptions:,在该方法中,一般都是应用启动后须要执行的初始化代码。
在Xcode中打开AppDelegate.m文件,找到applicationDidFinishLaunchingWithOptions方法,代码以下。
程序清单:codes/13/13.3/HelloWorld/HelloWorld/AppDelegate.m
-(BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// 建立程序主窗口
window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// 建立CCGLView对象,用于游戏中的渲染
// 从cocos2d v2.0以后,CCGLView替代了以前的EAGLView
// 使用CCGLView将OpenGL ES命令发送给OpenGL ES驱动
CCGLView *glView =[CCGLView viewWithFrame:[window_ bounds]
pixelFormat:kEAGLColorFormatRGB565depthFormat:0
preserveBackbuffer:NOsharegroup:nilmultiSampling:NO
numberOfSamples:0];
// ①建立导演对象
director_ =(CCDirectorIOS*) [CCDirector sharedDirector];
director_.wantsFullScreenLayout = YES;
// 将FPS(Frames Per Second)和SPF(Second Per Frame)显示设置为开
// cocos2d会自动计算游戏的当前帧数,并显示在屏幕的左下角
// 在调试过程当中FPS显示对咱们调试会很是有用
// 在游戏正式上传到设备时能够将其设置为NO,则FPS和SPF不会再显示在设备中
[director_ setDisplayStats:YES];
// 将动画间距设置为每秒60次,这也是cocos2d中的默认设置
// 在正常状况下,cocos2d每秒最高会刷新屏幕中的显示60次
[director_ setAnimationInterval:1.0/60];
// 将openglView绑定到director_导演对象上
[director_ setView:glView];
// 将director_的代理对象设置为self(自身),用于获取屏幕信息
[director_ setDelegate:self];
// 设置2D或3D投射
[director_ setProjection:kCCDirectorProjection2D];
// [director setProjection:kCCDirectorProjection3D];
// 启用Retina高清显示模式
if(! [director_ enableRetinaDisplay:YES] )
CCLOG(@"Retina Display Not supported");
// 设置cocos2d的纹理格式
[CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888];
// 在iPad或Retina高清显示模式下,使用CCFileUtils自动添加图片的后缀
CCFileUtils *sharedFileUtils = [CCFileUtils sharedFileUtils];
[sharedFileUtils setEnableFallbackSuffixes:NO];
[sharedFileUtils setiPhoneRetinaDisplaySuffix:@"-hd"];
[sharedFileUtils setiPadSuffix:@"-ipad"];
[sharedFileUtils setiPadRetinaDisplaySuffix:@"-ipadhd"];
// 设置PVR图像具有多重透明度
[CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
// ②初始化IntroLayer场景,并使用pushScene方法切换到该场景
[director_ pushScene: [IntroLayer scene]];
// 使用director_建立NavigationController导航控制器
navController_ = [[UINavigationController alloc] initWithRootViewController:director_];
// 设置navigationBarHidden为YES
navController_.navigationBarHidden = YES;
// 将NavigationController导航控制器设置为根视图控制器
[window_ setRootViewController:navController_];
// 设置主窗口可见
[window_ makeKeyAndVisible];
return YES;
}
在applicationDidFinishLaunchingWithOptions方法中,①号代码建立了一个CCDirector导演对象,在cocos2d中,CCDirector导演对象负责游戏的循环运行,而且在游戏中渲染全部的图像,它会掌控游戏的运行、暂停或中止。AppController中包括了CCDirector响应iOS操做系统在内的暂停或继续等各个事件。代码以下。
程序清单:codes/13.3/HelloWorld/HelloWorld/AppDelegate.m
// 当操做系统暂停应用时执行,调用此方法来暂停游戏和全部的计时器
// 当玩家在玩游戏的过程当中锁定了iPad或iPhone,或者有电话打进来
// 或者其余相似事件发生须要强迫游戏进入后台时,会调用此方法
-(void)applicationWillResignActive:(UIApplication *)application
{
if([navController_ visibleViewController] == director_ )
[director_ pause];
}
// 当玩家解锁iPad或iPhone,或电话已接听完毕时,会调用此方法来继续游戏和全部的计时器
-(void)applicationDidBecomeActive: (UIApplication *)application
{
if( [navController_ visibleViewController] == director_ )
[director_ resume];
}
// 在iOS 4.0及之后的版本中,开始支持应用在后台运行,此时会中止运行屏幕中的动画
-(void)applicationDidEnterBackground: (UIApplication*)application
{
if( [navController_ visibleViewController] == director_ )
[director_ stopAnimation];
}
// 当应用从新回到前台来运行时,从新启动屏幕中的动画
-(void)applicationWillEnterForeground: (UIApplication*)application
{
if( [navController_ visibleViewController] == director_ )
[director_ startAnimation];
}
// 应用程序即将停止时调用此方法
// 该方法会终止CCDirector的控制,并从应用程序的UIWindow中解除对CCGLView的绑定
// 同时还将结束游戏循环,从内存中清除全部的纹理和计时器
-(void)applicationWillTerminate: (UIApplication *)application
{
CC_DIRECTOR_END();
}
// 当系统收到内存不足的警告时,会调用此方法从内存中清除未在屏幕中显示的纹理图。
-(void)applicationDidReceiveMemoryWarning: (UIApplication *)application
{
[[CCDirector sharedDirector] purgeCachedData];
}
// 将上一次时间调用和当前事件调用间的增量时间设置为0。
// 该方法的调用场景是:两次调用之间已通过了太长的时间。
// 这一般是因为iPhone从新调整了系统时间而致使。
-(void)applicationSignificantTimeChange: (UIApplication *)application
{
[[CCDirector sharedDirector] setNextDeltaTimeZero:YES];
}
在applicationDidFinishLaunchingWithOptions方法中,编号②代码初始化IntroLayer场景,并使用pushScene方法切换到该场景。下面咱们来看看IntroLayer类的实现。
IntroLayer类继承自CCLayer,由于CCDirector只能运行CCScene对象,因此须要实现IntroLayer的scene方法,它会把IntroLayer看成惟一的子节点添加进去,并返回一个CCScene。打开IntroLayer.m文件,找到scene方法,代码以下。
程序清单:codes/13/13.3/HelloWorld/HelloWorld/IntroLayer.m
+(CCScene *)scene
{
// 建立CCScene场景对象
CCScene *scene = [CCScene node];
// 建立IntroLayer层对象
IntroLayer *layer = [IntroLayer node];
// 将layer添加为scene的子节点
[scene addChild: layer];
// 返回scene对象
return scene;
}
之前的cocos2d版本中是不存在IntroLayer类的,这是cocos2d 2.0新加的类,它的主要目的就是在进入游戏以前,能够显示游戏制做公司的Logo等信息。显示Logo的实现代码在onEnter方法当中,代码以下(程序清单同上)。
-(void)onEnter
{
[super onEnter];
// 得到设备支持的窗口大小
CGSize size = [[CCDirector sharedDirector] winSize];
CCSprite *background;
// 判断设备是iPhone仍是iPad,并据此来加载不一样的背景资源图片
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone ){
background = [CCSprite spriteWithFile:@"Default.png"];
background.rotation = 90;
} else {
background = [CCSprite spriteWithFile:@"Default-Landscape~ipad.png"];
}
// 设置背景图片的位置居中
background.position = ccp(size.width/2,size.height/2);
// 把背景图片添加到IntroLayer中
[self addChild: background];
// 触发一个定时器方法调用,在1秒后会调用makeTransition函数
[self scheduleOnce:@selector(makeTransition:)delay:1];
}
接下来看看makeTransition方法的实现,代码以下(程序清单同上)。
-(void)makeTransition: (ccTime)delta
{
[[CCDirector sharedDirector] replaceScene:
[CCTransitionFade transitionWithDuration:1.0
scene:[HelloWorldLayer scene] withColor:ccWHITE]];
}
该方法只有一句代码调用,就是使用CCDirector配合CCTransitionFade场景切换特效类,把HelloWorldLayer类在1秒屏幕变白后展现出来。最后来看看HelloWordLayer类的实现。
HelloWorldLayer类继承自CCLayer。由于CCScene只是一个抽象的接口,而默认设置场景的方法一般是在类里使用一个静态初始化方法+(id)scene。此方法会建立一个CCScene对象,而且将HelloWorldLayer的对象添加为场景的子节点。代码以下。
程序清单:codes/13/13.3/HelloWorld/HelloWorld/HelloWorldLayer.m
+(CCScene *)scene
{
// 建立CCScene场景对象
CCScene *scene = [CCScene node];
// 建立HelloWorldLayer层对象
HelloWorldLayer *layer = [HelloWorldLayer node];
// 将layer添加为scene的子节点
[scene addChild: layer];
// 返回scene对象
return scene;
}
接下来再看看-(id)init初始化方法的实现,代码以下(程序清单同上)。
-(id) init
{
if((self=[super init])) {
// 建立和初始化一个标签对象
CCLabelTTF *label = [CCLabelTTF labelWithString:@"Hello World"
fontName:@"Marker Felt" fontSize:64];
// 实例化获得一个CCDirector的单例,并得到窗口的尺寸
CGSize size = [[CCDirector sharedDirector] winSize];
// 将标签位置设置在屏幕中央,ccp是cocos2d对于CGPointMake的宏定义
label.position = ccp(size.width /2,size.height/2);
// 将label添加为scene的子节点
[self addChild: label];
// 下面是初始化游戏中心的成就榜和高分榜的代码,此处先略去暂时不讨论
}
return self;
}
以上就是HelloWorld项目的详细实现过程。读者以前已经学习过iOS基础知识,因此这里并无对全部类的全部实现代码进行逐行解释和分析。但经过以上详细代码分析,咱们初步了解了一个cocos2d应用的启动和运行过程,这将为之后开发更复杂的游戏或应用程序打下扎实的基础。
在HelloWorld项目中,使用了场景(CCScene)、层(CCLayer)、导演(CCDirector)等核心类,在cocos2d的开发中,几乎任何一款cocos2d游戏中都会用到这些类,因此了解它们的做用、属性和方法,以及如何将这些类组织在一块儿,是咱们学习cocos2d游戏开发的必修课。掌握了这些基本知识以后,你们就会发现使用cocos2d开发游戏其实很简单。接下来重点介绍cocos2d中的核心类。