(译)cocos2d菜单教程:第二部分

it2025-11-06  6

原文链接地址:http://www.iphonegametutorials.com/2010/09/07/cocos2d-menu-tutorial-part-2/

 

  如果你还没有阅读过第一篇教程的话,那么我建议你在继续之前,回过头去完成第一部分教程再回来。

  今天,我们将在上一篇教程之上添加一些东西,同时,我们会用到动画和layer之间的切换效果(transition)。

  这里有本教程的完整源代码。

  好了,正式出发吧!第一步,就是整理一下我们将要实现些什么东西。如果在编码之前,你不做任何的计划的话,那么你什么也做不成!下面是我们这篇教程将要实现的功能特性列表:

为credit场景和play场景添加一个新的层当从一个场景切换到另一个场景的时候,做一些transition。用文本构建菜单系统。

  我保证接下来的内容很直白,而且很容易。

  让我们先创建两个新类“PlayerLayer”和“CreditLayer”--为什么要有Credit Layer?好吧,其实就是让别人知道这个游戏是你做的。我真的希望“PlayLayer”很清晰明了,其实就是我们游戏的GameScene或者MainScene,就是你实际玩游戏的场景。

  因此,像之前添加“SceneManger”类一样,右键点击“Classes”分组,然后选择“Add”,再选择“New Files”,确保选择“Objective-c”选项,同时要保证同时创建.h文件被勾上,如下所示:

 

  同样的方法创建CreditsLayer:

 

  现在,我们有两个文件,但是里面啥也没有。。。别担心,我们马上会讲到如何添加里面的内容--首先是PlayerLayer.h文件:

#import "cocos2d.h"#import "SceneManager.h"@interface PlayLayer : CCLayer {}-(void) back: (id) sender;@end

现在是PlayerLayer.m文件:

#import "PlayLayer.h"@implementation PlayLayer-(id) init{ self = [super init];if (!self) {return nil; } CCMenuItemFont *back = [CCMenuItemFont itemFromString:@"back" target:self selector: @selector(back:)]; CCMenu *menu = [CCMenu menuWithItems: back, nil]; menu.position = ccp(160, 150); [self addChild: menu];return self;}-(void) back: (id) sender{ [SceneManager goMenu];}@end

 

  现在,CreditsLayer和PlayerLayer几乎差不多,除了名字不同以外。但是,为了教学的需要,我还是要展示出来--首先是CreditsLayer.h文件:

#import "cocos2d.h"#import "SceneManager.h"@interface CreditsLayer : CCLayer {}-(void) back: (id) sender;@end

  然后是CreditsLayer.m文件:

#import "CreditsLayer.h"@implementation CreditsLayer-(id) init{ self = [super init];if (!self) {return nil; } CCMenuItemFont *back = [CCMenuItemFont itemFromString:@"back" target:self selector: @selector(back:)]; CCMenu *menu = [CCMenu menuWithItems: back, nil]; menu.position = ccp(160, 150); [self addChild: menu];return self;}-(void) back: (id) sender{ [SceneManager goMenu];}@end

 

  这些文件现在都只干一件事情----有一个“back”菜单按钮,当用户点击的时候,就通过SceneManager调转到MenuLayer。然后,如果你现在编译运行的话,也不会有任何问题,但是,你点back的时候,并不会跳转到任何场景去。。。我们马上就会来解决这个问题!

  现在,我们回到SceneManager并作一些修改----添加两个方法“goPlay”和“goCredits”:

#import #import "MenuLayer.h"#import "PlayLayer.h"#import "CreditsLayer.h"@interface SceneManager : NSObject {}+(void) goMenu;+(void) goPlay;+(void) goCredits;@end

 

  同时,我们要向SceneManager.m里面添加两个方法的实现,它让我们能够跳转到PlayerLayer和CreditsLayer中去。

+(void) goPlay{ CCLayer *layer = [PlayLayer node]; [SceneManager go: layer];}+(void) goCredits{ CCLayer *layer = [CreditsLayer node]; [SceneManager go: layer];}

 

  因此,现在完整的SceneManager.m文件,看起来如下所示:

#import "SceneManager.h"@interface SceneManager ()+(void) go: (CCLayer *) layer;+(CCScene *) wrap: (CCLayer *) layer;@end@implementation SceneManager+(void) goMenu{ CCLayer *layer = [MenuLayer node]; [SceneManager go: layer];}+(void) goPlay{ CCLayer *layer = [PlayLayer node]; [SceneManager go: layer];}+(void) goCredits{ CCLayer *layer = [CreditsLayer node]; [SceneManager go: layer];}+(void) go: (CCLayer *) layer{ CCDirector *director = [CCDirector sharedDirector]; CCScene *newScene = [SceneManager wrap:layer];if ([director runningScene]) { [director replaceScene:newScene]; }else { [director runWithScene:newScene]; }}+(CCScene *) wrap: (CCLayer *) layer{ CCScene *newScene = [CCScene node]; [newScene addChild: layer];return newScene;}@end

 

  现在,我们只需要在MenuLayer中添加一些调用就可以了!

  首先,修改MenuLayer的头文件:

#import "cocos2d.h"#import "SceneManager.h"#import "PlayLayer.h"#import "CreditsLayer.h"@interface MenuLayer : CCLayer {}- (void)onNewGame:(id)sender;- (void)onCredits:(id)sender;@end

 

  因为,我们创建了“onNewGame”和“onCredits”两个函数,在第一部分里,我们并没有在MenuLayer.h里添加任何方法声明。当然,不要忘了#imports PlayerLayer.h和CreditsLayer.h两个头文件。

  最后,我们需要在MenuLayer.m文件里使用SceneManager来实现“onNewGame”和“onCredits”两个方法:

- (void)onNewGame:(id)sender{ [SceneManager goPlay];}- (void)onCredits:(id)sender{ [SceneManager goCredits];}

 

  哇!就这么多代码!现在编译并运行,你现在有一个菜单,可以从“Play”到“Menu”,以及“Credits”之间相互切换了。

  但是,看起来有点生硬,不够生动---接下来,让我们做一些更有趣的事情吧---来玩一玩transitons怎么样?:)

———————–New Note

  在2010年9月1日,cocos2d更新到0.99.5-beta2了,在Transition方面做了一此改变。一些名字被改动了,如果你之前使用的是0.99.4,如果更新到0.99.5的话,那么会有一些错误。

  下面是你需要做的一些更改,如果你是从0.99.4更新到0.99.5的话:

Transitions所有的Transition类都被重新命名了Old                           NewCCXXXTransition CCTransitionXXXExample:Old                     NewCCFadeTransition CCTransitionFade

你可以从下面的链接看到完整的更改列表:http://www.cocos2d-iphone.org/wiki/doku.php/release_notes:0_99_5———————–

  那么,我们怎么做呢?我们可以让SceneManager来完成所有的工作。好,我们先在“go”方法里面使用CCFadeTransition来replaceScene,如下所示:

[director replaceScene:[CCFadeTransition transitionWithDuration:1.2f scene:newScene withColor:ccWHITE]];

 

  从下载下来的cocos2d 测试代码中,找到Transition.h/.m,那里面有所有的transition的用法:

  以下是一些样例:

[CCFadeTransition transitionWithDuration:1.2 scene:newScene withColor:ccWHITE];[CCZoomFlipXTransition transitionWithDuration:1.2 scene:newScene orientation:kOrientationLeftOver];[CCFlipYTransition transitionWithDuration:1.2 scene:newScene orientation:kOrientationDownOver];

 

  我们将封装一下我们的类,使之接收两个参数“delay time”和“new scene”的名字。。。为了从场景的字符串名字获得场景类,我们所要下面这个方法:

Class c = NSClassFromString(r);"

 

  整个SceneManager类看起来如下所示:

#define TRANSITION_DURATION (1.2f)@interface FadeWhiteTransition : CCFadeTransition+(id) transitionWithDuration:(ccTime) t scene:(CCScene*)s;@end@interface ZoomFlipXLeftOver : CCZoomFlipXTransition+(id) transitionWithDuration:(ccTime) t scene:(CCScene*)s;@end@interface FlipYDownOver : CCFlipYTransition+(id) transitionWithDuration:(ccTime) t scene:(CCScene*)s;@end@implementation FadeWhiteTransition+(id) transitionWithDuration:(ccTime) t scene:(CCScene*)s {return [self transitionWithDuration:t scene:s withColor:ccWHITE];}@end@implementation ZoomFlipXLeftOver+(id) transitionWithDuration:(ccTime) t scene:(CCScene*)s {return [self transitionWithDuration:t scene:s orientation:kOrientationLeftOver];}@implementation FlipYDownOver+(id) transitionWithDuration:(ccTime) t scene:(CCScene*)s {return [self transitionWithDuration:t scene:s orientation:kOrientationDownOver];}staticint sceneIdx=0;static NSString *transitions[] = {@"FlipYDownOver",@"FadeWhiteTransition",@"ZoomFlipXLeftOver",};Class nextTransition(){// HACK: else NSClassFromString will fail [CCRadialCCWTransition node]; sceneIdx++; sceneIdx = sceneIdx % ( sizeof(transitions) /sizeof(transitions[0]) ); NSString *r = transitions[sceneIdx]; Class c = NSClassFromString(r);return c;}

 

  因此,最后修改一下“go”函数,首先,我们添加下面一行代码:

Class transition = nextTransition();

 

  然后,我们把下面的语句:

[director runWithScene:newScene];

  替换成:

[director replaceScene:[transition transitionWithDuration:TRANSITION_DURATION scene:newScene]];

 

  最终SceneManger的go函数看起来如下所示:

+(void) go: (CCLayer *) layer{ CCDirector *director = [CCDirector sharedDirector]; CCScene *newScene = [SceneManager wrap:layer]; Class transition = nextTransition();if ([director runningScene]) { [director replaceScene:[transition transitionWithDuration:TRANSITION_DURATION scene:newScene]]; }else { [director runWithScene:newScene]; }}

 

  很酷,对吧?

  好像这个教程还不够,我们还可以调加更多的效果。。。最后,我还想在菜单文本上面添加一些效果。为了实现这个,我们需要修改MenuLayer.m文件。  首先,我们先把titleLeft和titleRight CClabel从下面的代码:

titleLeft.position = ccp(80, 345);[self addChild: titleLeft];titleRight.position = ccp(220, 345);[self addChild: titleRight];

    改在下面的代码:

titleLeft.position = ccp(80, -80);[self addChild: titleLeft];titleRight.position = ccp(220, 520);[self addChild: titleRight];

  然后为每一个菜单项添加一个动画:

CCAction *titleRightAction = [CCSequence actions: [CCDelayTime actionWithDuration: delayTime], [CCEaseBackOut actionWithAction: [CCMoveTo actionWithDuration: 1.0 position:ccp(220,345)]],nil];

 

  oh!我的天,这在干嘛啊!

  创建一个CCAction对象,它由于系列的事件组成。

  这个事件序列首先等待0.3秒,然后移动到(220,345)的位置,时间间隔为1秒,同时用EaseBackOut修饰了,所以是先快后慢。

  一旦我们创建了这个动作序列之后,我们在titleLeft上面运行这个action。

[titleLeft runAction: titleLeftAction];

 

  我们同时要为titleRight添加类似的行为。

  最后的动画就是Menu本身:

for (CCMenuItemFont *each in [menu children]) { each.scaleX =0.0f; each.scaleY =0.0f; CCAction *action = [CCSequence actions: [CCDelayTime actionWithDuration: delayTime], [CCScaleTo actionWithDuration:0.5F scale:1.0], nil]; delayTime +=0.2f; [each runAction: action];}

 

  你可以讲讲上面的代码是干嘛用的吗?我们又创建了一个“Action”变量,先停0.3秒,然后0.5秒缩放到1.0。因为我们开始之前把scale设置为0,这样就可以在0.5秒的时间内,慢慢放大到100%的尺寸。让我们运行一下代码,体验一下吧!

 

 

再见!

 

著作权声明:本文由http://www.cnblogs.com/andyque翻译,欢迎转载分享。请尊重作者劳动,转载时保留该声明和作者博客链接,谢谢!

转载于:https://www.cnblogs.com/zilongshanren/archive/2011/07/15/2107760.html

相关资源:数据结构—成绩单生成器
最新回复(0)