当前位置:编程学习 > 网站相关 >>

cocos2d精灵教程:第一部分

前言:CocoaChina上有位网友问我能不能翻译一些比较高级的文章。首先,非常感谢这位网友的建议。之前翻译的3篇菜单教程,相比于前面TinyWings来说,确实显得有点小儿科了。但是,需要说明的是,那三篇菜单教程是后面教程的基础。在iphonegametutorials这个网站上,作者会引用到前面的文章。所以今天,我还是会翻译三篇“小儿科”的文章。不过希望大家还是耐着性子看一遍,权当温故知新。如果大家觉得哪些主题比较感兴趣,麻烦把E文链接发给我,我可以翻译。同时,我希望本博客能给游戏开发人员提供一些帮助,我希望有兴趣的开发人员能够加入到翻译的队伍中来,我需要你们的帮助,毕竟我一个人的时间和精力有限。当然,我们也可以自己写游戏开发教程:)。比如知易写的就很不错,通俗易懂。如果有意向一起翻译或者愿意写游戏教程的朋友,请加我qq:254041321。谢谢大家一直关注我!

  当然,如果有自己的博客,并且写了教程的,也可以把链接发给我,我转载并注明版权和出处。总之,我希望这个博客是我们共同的游戏开发博客。上面会有很多的资源和分享。希望得到你们的支持和参与,再次表示感谢!

----------------------------------------------------------------------------------------------------------------------

  朋友们,欢迎回来!今天,我们将要征服cocos2d里面的精灵。这个过程并不会像你想像中那么难,接下来的教程,我就会证明给你看。首先,我们有N种方法在屏幕上显示一张图片。。。其实,我们在《coco2d菜单教程:第三部分》就已经知道一种显示图片的方式了。


  那么,我们今天将学习哪些内容呢?我们将学习有关 “CCSprite”, “CCSpriteSheets”, “CCSpriteFrame”,以及“Texture2d” 和 “CCTextureCache”的一切!在这篇教程的最后,我们将有一条龙在一个简单的背景地形上面飞,路径由用户的手指滑动touch决定。很酷呢?

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

(。。。这里省略掉了一大段内容,讲的是0.99.5对api接口的变动,现在我们都用1.0了,这些内容我也不翻译了。。。)

    因此,在这个教程中,我们还是学习一些基础知识--不过没有菜单啦,我们主要关心的是精灵(sprite)。先看一看整个教程最后的产品是什么样子吧!如下图所示:

 \


  是否有点激动了呢?我敢打赌你现在很激动。。。不管怎么说,直接切入主题吧。。。

  首先,我们使用上个教程的 SceneManager.h/.m ,这里我们只创建“PlayLayer”类。

  我们首先要做的就是把“dragon.png”图片拖到Resources文件夹下去,它是一张750×560的图片,我把它缩小显示在下图。你可以从这里下载完整大小的图片资源。

 \


  那里面还有一张地形背景图,它的大小为480×320,我也把它缩小显示出来了:

 \


  像之前的菜单教程一样,把这里图片添加进resources分组下面去--你按住ctrl-click在“Resources”文件夹里面挑选你想要添加进工程的图片,记住,如果图片不是放在Reources文件夹下,那么最好选中 “copy to directory”复选框。

  好了,一旦你添加进去以后,它看起来的结构如下图所示:

 \


  我们的工程将包含两个类(delegate类除外): SceneManager 和 PlayLayer。我们已经知道SceneManger是如何工作的了,这里就不再啰嗦了。(可以参考《cocos2d菜单教程:第一部分》),但是,下面是我移除掉一些菜单选项后的SceneManager类。

SceneManager.h

#import #import "PlayLayer.h"@interface SceneManager : NSObject {}+(void) goPlay;@endSceneManager.m

#import "SceneManager.h"@interface SceneManager ()+(void) go: (CCLayer *) layer;+(CCScene *) wrap: (CCLayer *) layer;@end@implementation SceneManager+(void) goPlay{    CCLayer *layer = [PlayLayer 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
  一定要记得,把delegate类里面的CCDirector replaceScene调用,改成 “[SceneManager goPlay];”调用。

  好,如果你们都看了菜单教程的话,那么看到这里,你们可能会觉得烦了。所以,来点新鲜的吧:

PlayLayer.h

#import "cocos2d.h"#import "SceneManager.h"@interface PlayLayer : CCLayer {    NSMutableArray *_flyActionArray;    CCSprite *_dragon;    CCAction *_flyAction;    CCAction *_moveAction;    BOOL _moving;}@property (nonatomic, retain) NSMutableArray *flyActionArray;@property (nonatomic, retain) CCSprite *dragon;@property (nonatomic, retain) CCAction *flyAction;@property (nonatomic, retain) CCAction *moveAction;@end
  那么,这里做了些什么事呢?我们创建了三个实例变量:_dragon, _flyAction and _moveAction.从名字差不多也可以看出来它们到底是干什么用的,_dragon是我们的主角精灵,_flyAnimmation负责处理dragon的煽动翅膀的动画,而_moveAction负责处理从一点移动到另一个点。

  因此,CCSprite非常重要,但是,你可能会问你自己,我到底是应该继承CCSprite,还是包含一个CCSprite实例呢?我这里不使用一个Dragon类来继承CCSprite的原因是你可以从文件中加载一张图片来初始化它。这里有一个非常著名的问题:“Is-a”还是“has-a”?好吧,我的喜好是派生至CCNode,然后把所有的CCSprite当作它的属性。因为,我相信这样做会给你最大的灵性性。我承认,如果从CCSprite继承的话,刚开始会有许多方便之处,比如可以直接添加到BatchNode等。但是,我还是坚信,把CCSprite当作一个属性的话,你可以在以后的编程中获得巨大的好处。

  小提示:属性是objc提供给我们的一种方便地生成get/set方法的一种机制,同时还有其它一些好处,比如可以协助内存管理。

For example:

@interface HeroPlayer : NSObject {    NSString* weapon;    NSString* armor;}- (NSString*) weapon;- (NSString*) armor;- (void) setWeapon: (NSString*)input;- (void) setArmor: (NSString*)input;
   @property是objc声明属性的关键字,括号里面的retain指明set方法时,传入的参数会调用retain,使其引用计数加1.(译者:这样的话,你可以用self.xxx = [CCNode node];因为,cocos2d里面大量使用autorelease对象,这种对象出了当前mainLoop的话就会被release掉。所以,经常需要retain。而使用self.xxx = [CCNode node];的话,如果xxx属性里面的括号声明成了retain,那么就不用再retain了。简言之,self.xxx = [CCNode node];  和 xxx = [[CCNode node] retain];等价。但是,我们很少会在cocos2d里面retain什么东西,因为,我们基本上都会调用addChild方法,而这个方法会把参数自动retain一次,所以产生的autorelease对象才不会被释放掉。)

@implementation HeroPlayer@synthesize weapon;@synthesize armor;...@end
  @synthesize会自动为我们生成getter和setter。因此,我们只需要为这个类实现dealloc方法就可以了。

  访问器(getter/setter)只有当它们不存在的时候才生成,所以可以放心使用 @synthesize来声明属性,之后,你再可以按需要定制相应的getter和setter。编译器会判断哪个方法没有,然后自已生成之。

  好了,刚刚讲了一些题外话。。。接下来,让我们看看PlayLayer的实现:

PlayLayer.m

#import "PlayLayer.h"@implementation PlayLayer@synthesize flyActionArray = _flyActionArray;@synthesize dragon = _dragon;@synthesize moveAction = _moveAction;@synthesize flyAction = _flyAction;enum {    kTagSpriteSheet = 1,};-(id) init{    self = [super init];    if (!self) {        return nil;    }    CCSprite *background = [CCSprite spriteWith

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,