切页 是电子书的核心 320 * 416 UILabel电子书切页 NSString * s = @"asdfsdfasd"; CGSize maxSize = CGSizeMake(320, 2000); UIFont * font = [UIFont systemFontOfSize:16]; CGSize readSize = [s sizeWithFont:font constrainedToSize:maxSize lineBreakMode:UILineBreakMordWrap]; Cocos2D 游戏引擎就是,能够方便我们写游戏的一个中间库。 能够很好的帮助我们开发游戏。 关于Iphone游戏 需要的知识 1,Obj-C 2,简单的UIView和UIViewController cocos2D,->1.0 cocos2D,->2.0 用以下Cocos2D的库函数 场景 导演 Director 剧场(场景) Scene 精灵 sprite CCLayer 就相当于一个全屏的UIView 严格来讲,就是一个UIViewController OpenGL是一个图形库,ES代表嵌入式 在添加CCMenuItem对像时,如果没有添加事件, 则程序不能进行起来。 CCLayer声明了两个参数: BOOL isTouchEnabled_ 很好理解,是否支持触摸响应。 BOOL isAcceleromterEnabled_ 是否支持重力感应。 UIiamge 纹理 UIimageVIew 精灵 //让这个图片x上缩小0.2倍 yellowSprite.scaleX = 0.2 接下来我们就开始玩转cocos2D 以下教程很适合有Iphone开发基础的查看 首先用Xcode创建一个工程 选择Iphone 应用程序-》选择一个空的模版 然后加入以下几个库 图形库 CoreGraphics.framework OpenGLES库 OpenGLES.framework Quartz库 QuartzCore.framework 跨平台音效库 OpenAL.framework Audio AudioToolbox.framework 压缩库 libz.dylib 音效库 AVFoundation.framework 然后我们导入cocos2D的库,接下来我们就徒手开发一个 简单的cocos2D游戏 导入cocos2D的libs库 然后再导入添加一些Resources 导入cocos2D的头文件 只需要导入这一个头文件就行 #import "cocos2d.h"; 然后在didFinishLaunchingWithOptions函数中写入 // 1.0, setp:1 // 设置导演类型为kCCDirectorTypeDisplayLink // kCCDirectorTypeDisplayLink是一个最好的的类型 // ret 表示是否设置成功 BOOL ret = [CCDirector setDirectorType:kCCDirectorTypeDisplayLink]; if (!ret) { // kCCDirectorTypeDefault是缺省的导演, 这是最普通的导演类型 [CCDirector setDirectorType:kCCDirectorTypeDefault]; } // 导演就一个,所以在任何地方取导演,然后横屏 CCDirector * director = [CCDirector sharedDirector]; [director setDeviceOrientation:kCCDeviceOrientationLandscapeLeft]; // setp:2 创建舞台 //EAGLView:UIView 是一个可以画3D效果的UIView // 关联导演和舞台 EAGLView * gView = [[EAGLView alloc] initWithFrame:self.window.bounds]; [director setOpenGLView:gView]; // 设置frame60Hz [director setAnimationInterval:1/60.0f]; [director setDisplayFPS:YES]; // 把舞台展示在UI的界面上 [self.window addSubview:gView]; [gView release]; [CCTexture2D setDefaultAlphaPixelFormat:kCCTexture2DPixelFormat_RGBA8888]; [[CCDirector sharedDirector ] runWithScene:[StartScene scene]]; // 设置菜单的字体, 当然除了字体还有很多设置 [CCMenuItemFont setFontName:@"Arial"]; // 可以设置图片和Label等等 [CCMenuItem] [CCMenuItemAtlasFont]; [CCMenuItemFont]; [CCMenuItemImage]; [CCMenuItemLabel]; [CCMenuItemSprite]; [CCMenuItemToggle]; s // 添加完之后,进行cocos2D精灵的移动 [self addChild:target]; // 设置移动坐标 float minDuration = 2.0; float maxDuration = 4.0; float rangeDuration = maxDuration - minDuration; float actualDuration = (arc4random() % (int)rangeDuration) + minDuration; // 用cocos2D的 CCMoveTo 来进行移动 id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(-target.contentSize.width/2, actualY)]; // 移动完成后,可用CCCallFuncN 来调用一个方法执行。 id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)]; // 激活这些事件 [target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]]; 基本概念 为了全面掌握cocos2d-x的开发,我们首先需要了解该引擎的几个基本概念。实际上,这些基本概念是所有游戏开发所必须的,并非cocos2d-x专有。任何游戏都是通过这些概念所针对的对象组建起来的,游戏的复杂程度决定了这些对象实现的复杂程度。 场景(CCScene) 我们假设一个只有两关的游戏:第一关(2个小鬼,1个小BOSS);第二关(5个小鬼,1个大BOSS)。通常情况下,我们会这样设计整个游戏的流程(workflow): 开场动画,可以有几个目的: 简单介绍一下游戏操作 讲述故事背景 公司或者工作室动画LOGO 进入主菜单后可以引导用户: 开始新游戏 读取进度 设置游戏 声音,文字,游戏内容设置…… 高分排名 通常都是列表,按分数排列。 帮助 操作简介 退出 接下来,玩家可以有多种选择,无论开始新游戏还是读取进度,游戏都会进入到预设关卡。游戏过程中,第一关胜利就进入第二关,第二关胜利则进入结尾的胜利画面(播放视频或者在背景图上显示文字),确认后进入排名画面看看本次得了多少分。如果失败了,那就会进入失败结束的画面,确定后跳转到主菜单,重新开始。 可以看出,玩家玩游戏的过程就是在我们预设的画面之间进行跳转,根据玩家操作的结果(选择菜单项、消灭敌人或者被敌人杀死)跳转到不同的画面。 这些构成游戏流程的画面就是我们所说的场景,图中用黑色线框表示的部分。显然,不同的场景提供不同的操作,大致可以分为以下几类场景: 展示类场景:播放视频或简单的在图像上输出文字,来实现游戏的开场介绍、胜利/失败提示、帮助说明等。 选项类场景:主菜单、游戏参数设置等。 游戏场景:这是游戏的主要内容,除了这个场景之外,其他类别的场景基本都是通用框架实现的。 那么不同的场景是如何实现不同功能的呢?每个场景都是通过不同的层的叠加和组合来实现不同的功能的。因此,通常一个场景是由一个或多个层组成的。 层(CCLayer) 层是我们写游戏的重点,我们99%以上的时间是在层上实现我们的游戏内容。如下图所示,一个简单的主菜单画面是由3个层叠加实现的: 细心的读者可能已经注意到,为了让不同的层可以组合产生统一的效果,这些层基本上都是透明或者半透明的。(否则我们就只能看到最上面的一个层了) 层的叠加是有顺序的,如图所示,编号为1的背景层在最下层,2号在中间,3号在最上面。cocos2d-x也是按照这个次序来叠加画面的,处于最上层的不透明的部分会将下面的内容覆盖。 这个次序同样用于编程模型中的事件响应机制。即编号3的层最先接收到系统事件(手指单击屏幕事件),然后是编号2,最后是编号1的层。在事件的传递过程中,如果有一个层处理了该事件,那么排在后面的层将不再接收到该事件。 我们可以简单地把层理解为我们在Windows编程中的窗口(hWnd或者WinForm,还有Delphi中的TForm)。 为了方便大家进行游戏开发,cocos2d-x从技术实现角度提供一些公用层:处理菜单用的菜单层,处理颜色显示的颜色层等。 每一层又可以包含各式各样的内容要素:文本、链接、精灵、地图等等。其中,精灵是游戏的重点。 精灵(CCSprite) 精灵是整个游戏开发处理的主要对象。敌方的飞机、坦克是系统控制的精灵,玩家控制的我方飞机也是精灵,甚至随机飞过的一片云、一只鸟都是精灵。 从技术上讲,精灵就是一个可以不断变化的图片。这些变化包括:位移、旋转、缩放以及图片帧的切换。 所谓游戏,就是玩家操作一个或多个精灵与系统控制的精灵进行互动:近身肉搏、远程射击、对话等等。 导演(CCDirector) 我们已经大概了解了一个游戏的整体架构,不同的场景由不同的层组成,每个层又包含精灵在上面运动。玩家玩游戏的过程就是在操作层上的精灵或者菜单项,从而在不同的场景中切换。 好了,有些OO编程基础的读者已经猜到导演对象的作用了。是的,按照面向对象的设计原则和反向依赖原则:精灵不应该依赖层,层不应该依赖场景,场景不应该依赖整个流程。导演对象就是整个流程的代表,他负责游戏过程中的场景切换。 导演通常只有一个,因此这个对象是单例(singleton)。cocos2d-x框架已经预定义了该实例,无需额外创建,我们直接使用就可以。 导演对象接收层对象/场景对象的请求,按照预先设计好的流程来切换场景。至此,我们可以勾勒出一个游戏的整体框架和cocos2d-x关键对象与之的对应关系: 需要特别说明的是:任何时间,只有一个CCScene对象实例处于激活状态。该对象可以作为当前游戏内容的对象的容器,对于菜单对象来说,通常属于当前场景的主层。以上就是一个游戏的主要架构。 实际上,针对每一个游戏场景而言,不同场景(关卡)、每一个层(静态、动态)、每一个对象(敌人、我方、中立方)其实都很复杂。万里长征,这才第一步呢。 cocos2d-x的实现类 下面,我们首先逐一介绍cocos2d-x对应上述基本概念的对象,以及他们之间的程序关联。 CCDirector(导演类) CCDirector对象的作用类似于Windows编程中的主窗口对象(不同之处在于该对象并不可见),它负责创建、管理应用程序/游戏的主窗口,在特定的条件下显示某个场景。 针对CCDirector的调用代码(下面这段代码是主程序启动时的标准步骤,在AppDelegate的applicationDidFinishLaunching成员函数内实现): 1 bool AppDelegate::applicationDidFinishLaunching() 2 { 3 // initialize director 4 CCDirector *pDirector = CCDirector::sharedDirector(); 5 pDirector->setOpenGLView(&CCEGLView::sharedOpenGLView()); 6 7 // enable High Resource Mode(2x, such as iphone4) and maintains low resource on other devices. 8 // pDirector->enableRetinaDisplay(true); 9 10 // turn on display FPS 11 pDirector->setDisplayFPS(true); 12 13 // set FPS. the default value is 1.0/60 if you don't call this 14 pDirector->setAnimationInterval(1.0 / 60); 15 16 // create a scene. it's an autorelease object 17 CCScene *pScene = HelloWorld::scene(); 18 19 // run 20 pDirector->runWithScene(pScene); 21 return true; 22 } 显然,我们看到可以通过CCDirector对象完成以下两大类任务: 设置主程序窗口的显示属性。 依次设定了以下内容: 1.初始化CCDirector对象。 2.设置是否开启Retina显示模式。 3.设置是否显示FPS。 4.设置游戏画面每秒显示的帧数,默认是60帧。 管理、显示场景。 CCDirector对象一次只能显示一个场景。为了便于管理场景对象,CCDirector对象有3个属性与场景有关(参见CCDirector.h): 1 2 CCScene *m_pRunningScene; 3 4 5 CCScene *m_pNextScene; 6 7 8 CCMutableArray *m_pobScenesStack; 同时,CCDirector对象管理场景的方法主要有以下几个: 1 2 void runWithScene(CCScene *pScene); 3 4 5 void pushScene(CCScene *pScene); 6 7 9 void popScene(void); 10 11 12 void replaceScene(CCScene *pScene); 13 14 15 void end(void); 16 17 18 void pause(void); 19 20 21 void resume(void); CCScene(场景类) 场景对象当前比较简单,当前版本的cocos2d-x(1.0.1)基本上没有附加任何特殊功能,基本上可以看作是层(CCLayer)对象的一个容器。有些例子没有使用CCScene来作为场景切换,而是直接使用层的变换,笔者建议大家不要这样。CCScene的作用十分重要,如果要为场景切换增加动画效果,CCScene是必不可少的。 CCLayer(层类) CCLayer的主要功能在于: 1)接收触摸(touch)操作输入。 2)接收动力感知(Accelerometer)输入。 除此之外,CCLayer对象本身没有提供更多的功能。关于CCLayer对象与TouchDispatcher的相互作用关系,我们放在以后的章节重点介绍。 cocos2d-x为了方便大家使用,直接提供了以下4个层: CCLayerColor(颜色层) 这是一个透明的,可以按照RGB设置填充颜色的层。可以通过setContentSize设置层的大小,改变颜色块的尺寸。图中红色部分就是一个CCLayerColor的实例。 层也支持动作,可以变色、淡入淡出和混合。 CCLayerGradient(渐变层) CCLayerGradient是CCLayerColor的子类,他可以在背景上绘制渐变色。 CCMenu(菜单层) 这是一个以CCMenu对象为集合类,CCMenuItem类实例组成各式各样按钮的菜单管理选择画面层。(注意:该层中的实例必须是CCMenuItem类或其子类的实例) CCMenu类提供的方法主要是用来按照横向、竖向或者多行列排序展示CCMenuItem类实例的。 为了实现不同的按钮效果,系统提供了多种类型的CCMenuItem,但每个按钮都有三中基本状态:正常、选中、禁用。 下面,我们逐一介绍一下CCMenuItem类系: CCMenuItem CCMenuItem是基础类,不要直接使用该类。作为所有菜单项的父类,CCMenuItem主要完成以下两个任务: 1.设置按钮的状态。 2.负责处理回调函数(当按钮被单击后,需要调用的函数叫做回调函数)。具体说就是内置一个NSInvocation *invocation来统一实现回调函数的激活。(这段以后深入研究下再修正吧,在cocos2d-x里肯定不是) CCMenuItemLabel CCMenuItemLabel能将任何支持CCLabelProtocol协议的CCNode转变成一个菜单项,并增加选中时的放大效果。 CCMenuItemAtlasFont/CCMenuItemFont CCMenuItemAtlasFont和CCMenuItemFont都继承自CCMenuItemLabel,他们能根据你提供的字符串生成标签,并以此创建菜单项。他们的区别是CCMenuItemAtlasFont使用图片集,CCMenuItemFont使用预设字体。 CCMenuItemSprite CCMenuItemSprite内置3个支持CCRGBAProtocol协议的CCNode对象,表示正常、选中、禁用三个状态的图像。 CCMenuItemImage CCMenuItemImage从CCMenuItemSprite派生而来,你只需提供图片的名字,创建CCSprite对象的过程由框架自动完成。 CCMenuItemToggle 内部有一个CCMenuItem数组,负责展示不同的状态,进而达到状态切换的效果。 CCLayerMultiplex(复合层) 这是可以包含多个层的复合层,将来再专门介绍。 CCSprite(精灵类) 精灵是游戏中的主要静态、动态目标(敌方怪物、我方操作对象)。具体讲就是一个独立的图像块,通常情况下他是运动的(Action):位移、旋转、缩放、运动——连续渐变图像形成的运动效果。我们可以直接通过设定精灵的属性让他运动,也可以通过动作(Action)来达到同样的目的。 在cocos2d-x中精灵由CCSprite类实现。精灵允许包含子对象,当父对象变化的时候,子对象会跟着变化。 由于游戏中95%以上的内容都是精灵类实现模拟的,因此如何提高精灵类的执行效率就是一个十分关键的问题。 1)缓存图像内容,减少相同内容文件的读取次数。 通过CCTextureCache类,cocos2d-x库按照文件名为主键索引全部运行时读取的图片文件。当文件名一样时,直接返回内存中的图片而不再读取文件。 所有与图片文件有关的实现在底层统一调用CCTextureCache类的单例对象,保证最少的系统IO操作,提高程序运行效率。 2)批量提交绘画,减少OpenGL函数的调用次数。 通过CCSpriteBatchNode类,cocos2d-x库将所有CCSpriteBatchNode类对象所属的子CCSprite对象一次提交给OpenGL输出。 还有一个叫CCSpriteFrameCache的类,用于管理动画效果的全部帧图像。该类的实现也调用了CCTextureCache类对象。 小结 至此,读者对于cocos2d-x的几个关键概念以及对应的实现类有了整体的把握。CCScene、CCLayer、CCSprite类都是从CCNode类派生的,从类对象角度上来说他们是一样的,可以互相从属。从游戏设计的角度,他们完成的功能则互不相同,各有重点: 使用CCScene是为了: 1)作为某个场景的总体容器对象,将所有的内容对象(菜单、状态、游戏角色、NPC)包含在内,层叠关系通过CCNode的addChild的zOrder决定。 2)实现场景切换的特殊效果。因为所有的场景切换特效都是从CCScene的子类CCTransitionScene派生的。 使用CCLayer是为了处理输入问题: 1)触摸事件处理 2)动力感知处理 使用CCSprite是为了显示各式各样的精灵,展示游戏内容。