iPhone cocos2d游戏开发(2)

上一篇文章分析了游戏的结构,并做了基本的文档工作。这一篇文章,将完成游戏菜单的创建和显示功能。

本篇文章对应的源代码下载:My_Flight_Control_2010-06-16.zip

添加游戏菜单

启动XCode,新建一个基于“cocos2d Application”模版的新应用。应用名称为“My Flight Control”,后续文章里面就称我们的山寨版Flight Control为MYFC,而原版则称为FC。新建的应用除了显示cocos2d的logo和一个hello,world外,什么功能也没有,我们就在此基础上逐步实现MYFC。

游戏菜单具备几个条目,例如“开始新游戏”、“查看积分榜”、“查看帮助信息”等。除非是极其简单的游戏,否则添加一个游戏菜单是很有必要的。MYFC的菜单很简单,只有“Start Game”和“Scores”两项。

虽然菜单很简单,但我们还是将菜单分为MenuScene和MenuLayer两个对象。MenuScene包含一个菜单背景图和MenuLayer对象。MenuLayer对象则显示菜单项目,并响应玩家对菜单项目的点击。

创建MenuScene和MenuLayer对象

在XCode中新建文件,并选择cocos2d模版“CCNode class”,Subclass则设定为“CCLayer”。文件名输入MenuScene。

XCode_Create_MenuScene_Step1

新增的文件MenuScene.h和MenuScene.m会出现在Classes群组中:

MenuScene_Class.jpg

接下来重复上述步骤,再建立一个MenuLayer对象。

显示菜单背景

iPhone的分辨率是480×320,所以我们要做一个同等尺寸的png图片作为菜单背景图。做好的图片名为MenuBackground.png,拖入XCode中的Resources群组即可。

注意:拖入Resources群组时,如果MenuBackground.png原本没有存放在MYFC的目录中,则导入时需要选中“Copy items into destination group’s folder(is needed)”选项。

add_MenuBackground.jpg

有了资源,我们就可以进行编码了。

打开MenuScene.h文件,将:

@interface MenuScene : CCLayer

修改为:

@interface MenuScene : CCScene

然后再打开MenuScene.m文件,加入下面的代码:

01. - (id) init
02. {
03.     self = [super init];
04.     if (self) {
05.         // 取得屏幕大小
06.         CGSize winSize = [[CCDirector sharedDirector] winSize];
07.         // 将 MenuBackground.png 载入一个 CCSprite 对象实例
08.         CCSprite *bg = [CCSprite spriteWithFile:@"MenuBackground.png"];
09.         // 设定菜单背景的显示位置
10.         bg.position = ccp(winSize.width / 2, winSize.height / 2);
11.         // 将菜单背景添加到场景中
12.         [self addChild:bg];
13.     }
14.     return self;
15. }

CCDirector是cocos2d里面很重要的一个对象。这个对象充当游戏流程控制者的角色,让开发者可以根据需要切换不同的场景。由于CCDirector是一个单子模式实现,所以调用 [CCDirector sharedDirector] 可以获得CCDirector对象的唯一实例。

CCDirector除了控制流程,还有其他一些功能。此处我们用 [winSize] 消息来获得当前屏幕的大小。

接下来,使用CCSprite载入MenuBackground.png图片,并将这个Sprite添加到MenuScene的显示列表(显示列表的概念请参考本文后面部分)中。当MenuScene刷新画面时,MenuBackground.png的内容就会出现在屏幕上。

由于cocos2d载入一个图片后,会将图片的中心点做为原点。所以为了将图片显示在屏幕中央,需要设定图片的position属性。

Untitled-1.jpg

如上图,CCSprite的中心点默认在图片的中间。所以要将某个图片显示在屏幕中央,代码就是:

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

PS:ccp()是cocos2d定义的一个宏,是CGPointMake()的简写形式。

载入图片并调整好位置后,[self addChild:bg] 将包含背景图的CCSprite对象添加到MenuScene的显示列表中。

测试菜单背景

在编写MenuLayer的代码之前,我们先用MenuScene替换掉默认的hello,world。

打开My_Flight_ControlAppDelegate.m文件,将

#import "HelloWorldScene.h";

替换为:

#import "MenuScene.h";

再找到 applicationDidFinishLaunching 方法最后的

[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];

替换为:

[[CCDirector sharedDirector] runWithScene: [MenuScene node]];

确认无误后,运行模拟器即可看到菜单背景图了:

MenuScene.jpg

显示菜单项

菜单背景显示出来后,就该实现菜单项的显示了。这部分工作在MenuLayer对象中完成。这里我们使用cocos2d提供的CCMenuItem和CCMenu辅助类。这两个类可以创建一些简单的菜单,完全可以满足我们目前的需求。

打开MenuLayer.h文件,增加如下代码:

1. - (void) startGame: (id)sender;
2. - (void) scores: (id)sender;

打开MenuLayer.m文件,增加如下代码:

01. - (id) init
02. {
03.     self = [super init];
04.     if (self) {
05.         // 设定菜单项字体
06.         [CCMenuItemFont setFontName:@"Helvetica"];
07.         [CCMenuItemFont setFontSize:30];
08.   
09.         // 创建菜单项
10.         CCMenuItem *start = [CCMenuItemFont itemFromString:@"Start Game"
11.                                                     target:self
12.                                                   selector:@selector(startGame:)];
13.         CCMenuItem *scores = [CCMenuItemFont itemFromString:@"Scores"
14.                                                      target:self
15.                                                    selector:@selector(scores:)];
16.         // 创建菜单
17.         CCMenu *menu = [CCMenu menuWithItems:start, scores, nil];
18.         // 设定菜单项为垂直对齐
19.         [menu alignItemsVertically];
20.   
21.         // 添加菜单到显示列表中
22.         [self addChild:menu];
23.     }
24.     return self;
25. }
26.   
27. - (void) startGame: (id)sender {
28.     // 开始游戏
29. }
30.   
31. - (void) scores: (id)sender {
32.     // 显示得分记录
33. }

与添加背景一样的道理,最后需要把创建好的CCMenu对象添加到MenuLayer的显示列表中。

完成了对MenuLayer的修改,我们还要修改MenuScene对象,将MenuLayer包含的菜单项显示在背景之上。

打开MenuScene.m,在头部增加:

#import "MenuLayer.h"

修改init方法,在最后增加:

// 添加菜单层
[self addChild:[MenuLayer node]];

最终MenuScene.m中init方法的代码为:

01. - (id) init
02. {
03.     self = [super init];
04.     if (self) {
05.         // 取得屏幕大小
06.         CGSize winSize = [[CCDirector sharedDirector] winSize];
07.         // 将 MenuBackground.png 载入一个 CCSprite 对象实例
08.         CCSprite *bg = [CCSprite spriteWithFile:@"MenuBackground.png"];
09.         // 设定菜单背景的显示位置
10.         bg.position = ccp(winSize.width / 2, winSize.height / 2);
11.         // 将菜单背景添加到场景中
12.         [self addChild:bg];
13.   
14.         // 添加菜单层
15.         [self addChild:[MenuLayer node]];
16.     }
17.     return self;
18. }

这时再编译运行,就可以看到菜单项了:

iPhone Simulator-1.jpg

点击菜单项,还可以看到菜单项的放大缩小效果。

什么是显示列表?

虽然cocos2d没有明确提到“显示列表”这个概念,但实际上cocos2d是使用类似的技术来决定哪些对象应该显示在屏幕上。

在cocos2d中,所有出现在屏幕上的对象以一个树型结构来组织,例如MenuScene包含背景图和MenuLayer,而MenuLayer又包含几个菜单项目。这个树型结构中每一个节点都会维护一个列表。

例如MenuScene的显示列表中包含了背景图和MenuLayer对象。那么当MenuScene显示在屏幕上时,cocos2d就会把MenuScene显示列表中包含的对象也显示出来。如果MenuScene的显示列表中没有包含MenuLayer,则显示MenuScene时就不会显示MenuLayer对象。

DisplayList_Tree.jpg

当cocos2d刷新屏幕时,只有在显示列表中的对象会被绘制到屏幕上。因此如果我们有些对象不需要显示,则应该从显示列表中移除。

实质上,切换场景等操作就是对显示列表的调整。例如将场景从MenuScene切换为LeveScene,实际上就是从显示列表中移除MenuScene对象,再加入LevelScene对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值