频道栏目
读书频道 > 移动开发 > 其他综合 > iOS 5 cocos2d 游戏开发实战(第2版)
2.4 改变世界
2012-10-17 15:10:03     我来说两句
收藏   我要投稿
《iOS 5 cocos2d游戏开发实战(第2版)》将引导您开发富有吸引力的2D游戏。书中展示了如何使用cocos2d这款强大的游戏引擎来开发iPhone和iPad游戏,此外还介绍了游戏中的瓦片地图、虚拟摇杆、Game Center等。本书...  立即去当当网订购

如果我们仅仅是停留在通过模板生成的HelloWorld项目,仿佛对于深入了解cocos2d没有什么好处。我们需要亲自动手,改变世界!

首先,需要在init 方法中进行两处修改:一处是启用触摸输入;另一处是设置tag 属性以便日后对标签对象进行调用。在程序清单2-3中强调了这两处修改:

程序清单2-3   允许标签对象被触摸和访问

-(id) init
{
if ((self = [super init])) {
// create and initialize a label
CCLabelTTF* label = [CCLabelTTF labelWithString:@"Hello World"
fontName:@"Marker Felt"
fontSize:64];
// get the window (screen) size from CCDirector
CGSize size = [[CCDirector sharedDirector] winSize];
// position the label at the center of the screen
label.position = CGPointMake(size.width / 2, size.height / 2);
// add the label as a child to this Layer
[self addChild: label];
// our label needs a tag so we can find it later on
// you can pick any arbitrary number
label.tag = 13;
// must be enabled if you want to receive touch events!
self.isTouchEnabled = YES;
}
return self;
}

标签对象的tag 属性被设定为13。为什么要这样做呢?在前面的章节中,我说过这样做可以方便你以后通过标记来访问类的子对象。标记数字必须为正整数,并且每个对象的标记必须不同。否则,当出现两个相同的标记时,就很难区分到底要获取哪个对象了。

提示:

你应该养成定义常量来作为标记的习惯,而不该使用像13这样的具体数字。与TagForLabel这种拥有高可读性的变量名相比,13这个标记实在是很难让人记住。我将在第5章对此进行具体讨论。

然后,将self.isTouchEnabled设置为YES。这是CCLayer类的一个属性,表示你希望接收触摸消息。ccTouchesBegan方法只有在这种情况下才会被调用:  

-(void) ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
CCLabelTTF* label = (CCLabelTTF*)[self getChildByTag:13];
label.scale = CCRANDOM_0_1();
}

通过调用[self getChildByTag:13],可以使用tag 属性来访问CCLabelTTF对象,因为在init 方法中已经作过相应设置。然后就可以正常使用CCLabelTTF对象了。在本例中,我们使用cocos2d的CCRANDOM_0_1()宏来改变CCLabelTTF对象的scale属性,使之在0和1之间变化。每次当你用手指轻拍屏幕时,标签尺寸都会发生变化。

由于getChildByTag方法总是会返回标签,因此可以将它转换成CCLabelTTF*对象。但是,假如返回的不是派生自CCLabelTTF类的标签对象,游戏就会崩溃。如果你不小心将另一个对象的tag 属性也设为13的话,这样的事情就很容易发生。为此,我们应该采取防御型的编程风格,应该经常对得到的对象进行验证。通常可以使用断言的方法来验证假设是否成立。为此,可以使用NSAssert方法:

-(void) ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event;
{
CCNode* node = [self getChildByTag:13];
// defensive programming: verify the returned node is a CCLabelTTF
NSAssert([node isKindOfClass:[CCLabelTTF class]],  
@"node is not a CCLabelTTF!");
CCLabelTTF* label = (CCLabelTTF*)node;
label.scale = CCRANDOM_0_1();
}

在上述示例中,我们希望getChildByTag返回一个派生自CCLabelTTF类的对象,但是我们不能确定。所以,通过使用NSAssert来验证返回的对象,从而帮助我们在引发程序崩
溃前及时发现错误。

这样做虽然多写了两行代码,但是执行效率与先前无异。因为在最终的发布版本中,NSAssert将被删除,而“CCLabelTTF* label = (CCLabelTTF*)node;”这句执行类型转换的代码同样存在于第一个版本中。所以这两个版本的代码执行效率是完全一样的,但是使用第二个版本有一个好处:如果你没有得到希望的CCLabelTTF对象,那么将接收到EXC_BAD_ACCESS报错通知而不是直接引发程序崩溃。

您对本文章有什么意见或着疑问吗?请到论坛讨论您的关注和建议是我们前行的参考和动力  
上一篇:2.3 cocos2d中的内存管理问题
下一篇:2.5 你还应该知道的
相关文章
图文推荐
排行
热门
最新书评
特别推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站