第5章 游戏组件
5.1 使用多个场景
5.1.1 添加多个场景
CCNode有三个方法,使用CCDirector的replaceScene方法替换场景时,每个节点都会调用这三个方法。
onEnter与onExit方法在场景改变过程中的特定时刻被调用,这取决于是否使用CCTransitionScene。必须总是调用这些方法的超类实现了避免输入问题和内存泄露。
注意:
如果在onEnter方法中不调用超类实现,新场景不会对触摸输入或加速计输入作出响应。如果在onExit方法中不调用超类实现,当前场景就不会从内存中释放。有必要强调这一点,因为这些已被忘记,且造成的后果不会使人联想到与它们有关。
与在节点的init或dealloc方法中编写相同的代码不同的是,在onEnter方法被执行时场景已经完全建立好,而在onExit方法被执行时场景仍然包含所有的节点。
注意,最后一个被调用的方法是FirstScene的dealloc方法。这意味着在onEnterTransitionDidFinish方法执行的过程中,前一个场景仍然在内存中。这时如果要创建内存密集型节点,就需要指定选择器在进行内存分配钱至少等待一帧以保证前一个场景已从内存中释放,或者在前一个场景的onExit方法中释放尽可能多的内存。
5.1.2 正在加载下一段,请做好准备
提示:
将enum的第一个值设为无效值(INVALID)是很好的做法,除非你希望将第一个值设为默认值。Objective-C中变量的值会自动被初始化为0,指定了其他值的情况除外。
注意:
为何不直接在init方法中调用replaceScene呢?关于这点有两条规则。规则一:永远不在节点的init方法中调用CCDirector的replaceScene方法。规则二:遵守第一条规则。原因:程序会崩溃。Director无法应付一个正被初始化的节点中替换场景的情况。
5.2 使用多个层
5.2.1 实现关卡的最佳方法
在cocos2d中有两种方法,要么使用场景实现关卡,要么使用独立的层来管理不同的关卡。
1.使用场景
实现关卡最直接的方法就是将每一关作为单独的场景来管理。你可以为关卡创建一个新的Scene类,或者初始化一个公用的LevelScene类,并将关卡号或其他必要信息作为参数传入来加载相应的关卡数据。
在以下情况使用这种方法最为合适:关卡之间相互独立(上一关中发生的事与下一关无关);玩家晋级时只需保存玩家的得分和剩余生命数;用户界面纯粹用来显示信息,也许除了一个暂停按钮外就没有任何交互元素了。
2.使用层
如果用户界面复杂且在关卡改变时不能被重置,或者希望换关时保持玩家和其他游戏对象不变,那么推荐在同一场景中使用单独的层加载并显示关卡。
对于游戏中的隐藏对象,或者需要不断从一间屋子进入另一间屋子的冒险类游戏来说,使用层也许是理想的解决方案,尤其是对于需要在用户界面下使用移入或移出动画替换关卡内容的情景。
5.2.2 CCColorLayer
cocos2d提供CCColorLayer用于改变背景色,用法如下:
CCColorLayer* colorLayer=[CCColorLayer layerWithColor
:ccc4(255,0,255,255)];
使用OpenGL可以得到同样的效果:
glClearColor(1,0,1,1);
但请先测试一下游戏的场景过渡,因为改变glClearColor会对场景过渡产生不利影响。举例来说,当使用CCFadeTransition时,不管使用什么颜色初始化CCFadeTransition,透明色最终都会完全显现出来。
5.3 从CCSprite类继承游戏对象
游戏对象常常需要实现其自身的逻辑。这样一来,为每种游戏对象创建单独的类就显得很有意义。这包括玩家角色、各色敌人、子弹、导弹、平台和其他任何单独放置于游戏场景中并执行独立逻辑的对象。
5.4 使用CCSprite复合游戏对象
创建一个新的类,使其派生自Objective-C的基础类NSObject而不是之前的CCNode类。
5.5 奇妙的CCNode派生类
5.5.1 CCProgressTimer
进度计时器适用于任何类型的进度显示,如显示进度条或是使图标变回有效。进度计时器使用一个精灵,并基于百分比,只使一部分的到显示来表现进度特征。
timer.type是定义在CCProgressTimer.h头文件中的CCProgressTimeType枚举类型。有三种类型的进度计时器可供选择,分别是径向、纵向和横向。但这里有一点要警惕:计时器不会更新它自己。
5.5.2 CCParallaxNode
视差通常用于2D游戏,它通过将不同层次的图像以不同速率运动来得到景深效果。前景图像比背景图像的移动速度快。cocos2d中有专门的节点用于创建视差效果。
创建CCParallaxNode节点的步骤与其他类型节点无异,但在向其添加子节点时使用了特殊的初始化器。这里的parallaxRatio参数属于CGPoint类型,它是CCParallaxNode中任何移动的乘数因子。
注意:
一旦将子节点添加到CCParallaxNode之后,就不能修改子节点的位置了。最底层的图像滚动到尽头会露出下面的背景。修改CCMoveBy动作使CCParallaxNode移动更远一点,就可以看到这个现象。要增加滚动的距离,可以添加更多相同精灵并设置合适的偏移。但如果要求单向或双向无限滚动,就必须实现自己的视差系统。
5.5.3 CCRibbon
CCRibbon节点使用一队图像创建链状效果。
配合使用触摸输入,CCRibbon类可以实现热门游戏中的画线效果。值得注意的是,CCRibbon不支持移除单个点,只能将整个CCRibbon作为子节点从其父节点中移除。CCRibbon初始化器中的宽度和高度参数决定了单个ribbon元素的尺寸。
5.5.4 CCMotionStreak
本质上讲,CCMotionStreak相当于CCRibbon的一个封装。使用它可以使CCRibbon已显示的元素表现出不同程度的淡出效果。
CCMotionStreak的用法类似与CCRibbon,但现在CCRibbon已称为CCMotionStreak的一个属性。其中的fade参数指明ribbon元素淡出的速度:数字越小,消失得越快。而minSeg参数貌似没有明显的效果,尽管将它设为负值时会出现有趣的图像错误。
<!--EndFragment-->