使用cocos2d为游戏加入菜单场景

cocos2d拥有很完美的菜单管理和场景切换类,你可以使用它们为你的游戏加入菜单,完成场景之间的切换。

这次我会简单的介绍一下如何使用cocos2d提供的类库为游戏加入漂亮的菜单场景。在这一课你将会接触到菜单项的处理和场景的切换等相关知识。我不会讲述大篇幅的技术理论,我认为太多的理论对于一个初学者不仅没有帮助,反而会让他失去学习的乐趣。个人认为从实例代码下手更好,经过多次的实践之后,让读者自己去参悟其中的理论会更有效。

抛开题外话,让我们继续本章的主题。首先,让我们来创建我们的菜单类,这个类将包含两个部分,菜单场景类和菜单层类。因此我们在工程classes文件中建立一个New Group来存放管理他们会更方便。右击classes类文件夹,在弹出的菜单项中选择Add─>New Group创建一个新的Group,并将他命名为Menu。然后右击Menu文件夹,在弹出的菜单项中选择Add─>New File依次创建两个基于CCLayer的类文件,分别将它们命名为MenuScene和MenuLayer。这时你的Menu文件夹下应该有4个文件,分别是:MenuScene.h,MenuScene.h ,MenuLayer.h和MenuLayer.m文件。下面直接贴代码了:

 

 

MenuScene.h中的代码如下:

 

 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

@interface MenuScene : CCLayer {

}

 

+(id) scene;

 

@end

 

 

MenuScene.m中的代码如下:

 

 

#import "MenuScene.h"

#import "MenuLayer.h"

 

@implementation MenuScene

 

// 实例化本场景

+(id) scene

{

// 'scene' is an autorelease object.

CCScene *scene = [CCScene node];

MenuScene *layer = [MenuScene node];

[scene addChild: layer];

return scene;

}

 

// 初始化函数

- (id) init

{

self = [super init];

if (self

{

// 设定菜单背景

CGSize winSize = [[CCDirector sharedDirector] winSize]; 

CCSprite *bg = [CCSprite spriteWithFile:@"MenuBackground.png"];

bg.position = ccp(winSize.width / 2, winSize.height / 2);

[self addChild:bg];

// 添加菜单层

[self addChild:[MenuLayer node]];

}

return self;

}

 

// on "dealloc" you need to release all your retained objects

- (void) dealloc

{

[super dealloc];

}

 

@end

 
MenuLayer.h中的代码如下:
 

 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

@interface MenuLayer : CCLayer {

}

 

// 下面声明的三个方法是菜单的三个选项,开始游戏,分数和关于

- (void) startGame: (id)sender;

- (void) scores: (id)sender;

- (void) onAbout: (id)sender; 

 

@end

 

 

 

 
MenuLayer.m中的代码如下:
 

#import "HelloWorldScene.h"

#import "MenuLayer.h"

#import "ScoreScene.h"

#import "AboutScene.h"

 

@implementation MenuLayer

 

// on "init" you need to initialize your instance

- (id) init

{

self = [super init];

if (self

{

// 设定菜单文字

[CCMenuItemFont setFontName:@"Helvetica"];

[CCMenuItemFont setFontSize:30];

CCMenuItem *start = [CCMenuItemFont itemFromString:@"Start Game"

target:self

  selector:@selector(startGame:)];

CCMenuItem *scores = [CCMenuItemFont itemFromString:@"Scores"

target:self

  selector:@selector(scores:)];

CCMenuItem *abouts = [CCMenuItemFont itemFromString:@"About" 

target:self 

  selector:@selector(onAbout:)];

CCMenu *menu = [CCMenu menuWithItems:start, scores, abouts, nil];

[menu alignItemsVertically];

// 菜单特效可有可无,实现一个菜单飞出式效果

CGSize s = [[CCDirector sharedDirector] winSize];

int i=0;

for( CCNode *child in [menu children] ) {

            CGPoint dstPoint = child.position;

            int offset = s.width/2 + 50;

            if( i % 2 == 0)

                offset = -offset;

            child.position = ccp( dstPoint.x + offset, dstPoint.y);

            [child runAction:[CCEaseElasticOut actionWithAction:[CCMoveBy actionWithDuration:2 position:ccp(dstPoint.x - offset,0)]period: 0.35f]];

            i++;

        }

[self addChild:menu];

}

return self;

}

 

// 实现菜单方法

// 切换到StartGame场景

- (void) startGame: (id)sender 

{

CCScene *sc = [CCScene node];

[sc addChild:[HelloWorld node]];

// 缩放的形式切换场景

[[CCDirector sharedDirector] replaceScene: [CCShrinkGrowTransition transitionWithDuration:1.2f scene:sc]];

}

 

// 切换到Scores场景

- (void) scores: (id)sender 

{

CCScene *sc = [CCScene node];

[sc addChild:[ScoreScene node]];

// 缩放的形式切换场景

[[CCDirector sharedDirector] replaceScene: [CCShrinkGrowTransition transitionWithDuration:1.2f scene:sc]];

}

 

// 切换到About场景

- (void) onAbout: (id)sender 

{

CCScene *sc = [CCScene node];

[sc addChild:[AboutScene node]];

// 缩放的形式切换场景

[[CCDirector sharedDirector] replaceScene: [CCShrinkGrowTransition transitionWithDuration:1.2f scene:sc]];

}

 

// on "dealloc" you need to release all your retained objects

- (void) dealloc

{

[super dealloc];

}

 

@end

 

 

 

 

到这里菜单类的编写就结束了,这里运用了场景和层分离的概念。将菜单场景与菜单层分开实现,这样可以使代码更加的清晰,层次更加分明。但是现在你还无法成功的运行你的程序,因为还有菜单项没用实现。另外你还没有修改Delegate.m托管文件中首场景载入函数的参数,你需要让它指向你编写的菜单场景。下面我们就来完成剩下的工作。首先,用同样的方法在classes文件夹下创建名为MenuOption的组,并在其下创建两个基于CCLayer的类文件,分别命名为AboutSceneScoreScene。然后打开Delegate.m托管文件,将头文件"HelloWorldScene.h"改为"MenuScene.h"。再在- (void) applicationDidFinishLaunching:(UIApplication*)application 方法的最后一行找到 [[CCDirector sharedDirector] runWithScene: [HelloWorld scene]]; 这段函数调用,将参数中的HelloWorld改为刚创建的MenuScene场景。下面贴出菜单项类的代码:

 

HelloWorldScene.h中的代码如下:

 

 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

// HelloWorld Layer

@interface HelloWorld : CCLayer {

}

 

@end

 

HelloWorldScene.m中的代码如下:

 

 

#import "HelloWorldScene.h"

#import "MenuScene.h"

 

// HelloWorld implementation

@implementation HelloWorld

 

// on "init" you need to initialize your instance

-(id) init

{

// always call "super" init

// Apple recommends to re-assign "self" with the "super" return value

if( (self=[super init] )) {

// create and initialize a Label

CCLabel* label = [CCLabel labelWithString:@"Hello World" fontName:@"Marker Felt" fontSize:64];

 

// ask director the the window size

CGSize size = [[CCDirector sharedDirector] winSize];

// position the label on the center of the screen

label.positionccp( size.width /2 , size.height/2 );

// add the label as a child to this Layer

[self addChild: label];

// 添加图形返回菜单

CCSprite *menuNormal = [CCSprite spriteWithFile:@"b_back.png" rect:CGRectMake(0, 0, 78, 41)];

CCSprite *menuSelected = [CCSprite spriteWithFile:@"b_back_s.png" rect:CGRectMake(0, 0, 78, 41)];

CCMenuItemSprite *backToMenu = [CCMenuItemSprite itemFromNormalSprite:menuNormal selectedSprite:menuSelected target:self selector:@selector(onBack:)];

CCMenu *menu = [CCMenu menuWithItems: backToMenu, nil];

[menu setPosition:ccp(480 - 50, 320 - 30)];

[self addChild: menu];

}

return self;

}

 

// 返回菜单方法

-(void) onBack: (id) sender

{

CCScene *sc = [CCScene node];

[sc addChild:[MenuScene node]];

[[CCDirector sharedDirector] replaceScene: [CCSlideInRTransition transitionWithDuration:1.2f scene:sc]];

}

 

// on "dealloc" you need to release all your retained objects

- (void) dealloc

{

// in case you have something to dealloc, do it in this method

// in this particular example nothing needs to be released.

// cocos2d will automatically release all the children (Label)

// don't forget to call "super dealloc"

[super dealloc];

}

@end

 

 

AboutScene.h中的代码如下:

 

 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

@interface AboutScene : CCLayer {

 

}

 

@end

 

 

 

 

 

 

AboutScene.m中的代码如下:
 

#import "AboutScene.h"

#import "MenuScene.h"

 

@implementation AboutScene

 

// on "init" you need to initialize your instance

-(id) init

{

if( (self=[super init] )) {

// Label显示作者

CCLabel* label = [CCLabel labelWithString:@"作者:谢映宇" fontName:@"Marker Felt" fontSize:40];

CGSize size = [[CCDirector sharedDirector] winSize];

label.positionccp( size.width /2 , size.height/2 );

[self addChild: label];

// 添加返回菜单

[CCMenuItemFont setFontSize:20];

CCMenuItem *backToMenu = [CCMenuItemFont itemFromString:@"Back" target:self selector:@selector(onBack:)];

CCMenu *mn = [CCMenu menuWithItems:backToMenu, nil];

[mn alignItemsVertically];

mn.position = ccp (480 - 50, 30);

[self addChild:mn z:1 tag:2];

}

return self;

}

 

// 返回菜单方法

-(void) onBack: (id) sender

{

CCScene *sc = [CCScene node];

[sc addChild:[MenuScene node]];

[[CCDirector sharedDirector] replaceScene: [CCSlideInRTransition transitionWithDuration:1.2f scene:sc]];

}

 

// on "dealloc" you need to release all your retained objects

- (void) dealloc

{

[super dealloc];

}

 

@end

 
ScoreScene.h中的代码如下:
 

#import <Foundation/Foundation.h>

#import "cocos2d.h"

 

@interface ScoreScene : CCLayer {

 

}

 

@end

 
ScoreScene.m中的代码如下:
 

#import "ScoreScene.h"

#import "MenuScene.h"

 

@implementation ScoreScene

 

// on "init" you need to initialize your instance

-(id) init

{

if( (self=[super init] )) {

 

// Label显示分数

CCLabel* label = [CCLabel labelWithString:@"最高分:9999" fontName:@"Marker Felt" fontSize:40];

CGSize size = [[CCDirector sharedDirector] winSize];

label.positionccp( size.width /2 , size.height/2 );

[self addChild: label];

// 添加返回菜单

[CCMenuItemFont setFontSize:20];

CCMenuItem *backToMenu = [CCMenuItemFont itemFromString:@"Back" target:self selector:@selector(onBack:)];

CCMenu *mn = [CCMenu menuWithItems:backToMenu, nil];

[mn alignItemsVertically];

mn.position = ccp (480 - 50, 30);

[self addChild:mn z:1 tag:2];

}

return self;

}

 

// 返回菜单方法

-(void) onBack: (id) sender

{

CCScene *sc = [CCScene node];

[sc addChild:[MenuScene node]];

[[CCDirector sharedDirector] replaceScene: [CCSlideInRTransition transitionWithDuration:1.2f scene:sc]];

}

 

// on "dealloc" you need to release all your retained objects

- (void) dealloc

{

[super dealloc];

}

 

@end

 
上面的代码都带有注释,有一定cocos2d基础的朋友很容易就能够看懂,初学者看的不是很明白也没有关系,可以先拿这些代码在程序中使用。在实践中就会慢慢的理解这些代码的含义了。

最后祝愿大家学习愉快,在这里可以下载到这篇文章的源代码:http://down.51cto.com/data/137061

 

 

 

 

 

你可能感兴趣的:(游戏,cocos2d,iPhone,菜单,休闲)