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

cocos2d精灵教程:第三部分

我们在第2部分教程中已经介绍了如何让dragon沿着8个不同的方向移动,并且播放相应的动画,同时,移动过程可以由用户touch屏幕来控制。cocos2d很酷吧!好了,今天我们将多干点活,我们将创建一大批村民--实际上是N个村民。我们会使用我们已经学习过的技术,从spritesheet里面加载精灵,同时建立相应的精灵动画。

 

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

  那么,我们到底要做成什么样子呢---看了下面的图就明白了:

 \


    上面加载了好多村民,但是,屏幕的帧速率仍然是60 fps。这是因为我们做了优化。那么,究竟是如何做的呢?让我们马上开始学习吧。

    首先,我们要创建我们的adventurer (冒险者)类。---它里面存储了我们的移动和行走动画的精灵实例。在屏幕上每一个冒险家,我们都会为之创建一个adventurer 类的实例。

Adventurer.h

#import "cocos2d.h"@interface Adventurer : CCNode {    CCSprite *_charSprite;    CCAction *_walkAction;    CCAction *_moveAction;    BOOL _moving;}@property (nonatomic, retain) CCSprite *charSprite;@property (nonatomic, retain) CCAction *walkAction;@property (nonatomic, retain) CCAction *moveAction;@end
    如果你愿意的话,你也可以从CCSprite继承,然后我们可以调用initWithFile方法来初始化我们的Adventure 类。但是,我更喜欢从CCNode继承,然后包含一个CCSprite的实例。

Adventurer.m

#import "Adventurer.h"@implementation Adventurer@synthesize charSprite = _charSprite;@synthesize moveAction = _moveAction;@synthesize walkAction = _walkAction;-(id) init{    self = [super init];    if (!self) {        return nil;    }    return self;}- (void) dealloc{    self.charSprite = nil;    self.walkAction = nil;    self.moveAction = nil;    [super dealloc];}@end
    很简单的init函数,同时我们还定义了一个dealloc方法。(译者:大家一定要养成一个好习惯,定义init就马上定义dealloc,“创建-销毁”要成对,这个很重要,能减少很多内存问题。stackoverflow上面,有人直接把dealloc方法放在.m文件的最开头,作用不言而喻!ios内存有限啊!)---上面这段代码,我们再熟悉不过了。这里创建了一个非常简单的类,但是,也给我们一些提示,如何为游戏主角创建class。这里把所有的属性都定义了retain说明符,同时在dealloc方法里面调了self.xxx = nil来释放内存。这样就把内存管理与property关联起来了。objc的引用计数已经为我们程序员减少了对于内存管理的烦恼,因此,只需要养成良好的习惯,就可以减少大量与内存有关的问题发生。

    现在,我们拥有角色了,让我们来使用之。。。先回到“PlayLayer.h” ,然后做下面一些变更:

#import "cocos2d.h"#import "SceneManager.h"#import "Adventurer.h"@interface PlayLayer : CCLayer {    CCTexture2D *_texture;    CCSpriteSheet *_spriteSheet;    NSMutableArray *_charArray;}@property (nonatomic, assign) CCTexture2D *texture;@property (nonatomic, assign) CCSpriteSheet *spriteSheet;@property (nonatomic, retain) NSMutableArray *charArray;@end
    我们先导入 “Adventurer.h”,然后定义了3个实例变量。第一个变量 “_texture”用来加载adventurer 精灵表单。第二变量 “_spritesheet”是把我们将要创建的精灵都进行“批处理”,使之提高效率。最后,我们想要追踪所有的adventurers,所以,我们定义了一个“_charArray”.数组。同时我们为每一个实例变量都声明了属性,这样我们就可以在PlayLayer.m间接使用了。(另一种方法是定义tag,在init方法里面指定tag,然后在其它方法里面就可以用self getChildByTag:tag来获得想要的孩子了)

    OK,现在我们有一堆类了。不过别担心,我们会在后面把它逐步分开讲解--首先,先让我们实现PlayLayer.m:

PlayLayer.m

#import "PlayLayer.h"#import "Adventurer.h"@implementation PlayLayer@synthesize texture = _texture;@synthesize spriteSheet = _spriteSheet;@synthesize charArray = _charArray;enum {    kTagSpriteSheet = 1,};-(id) init{    self = [super init];    if (!self) {        return nil;    }    CCSprite *background = [CCSprite spriteWithFile:@"Terrain.png"];    background.position = ccp(160, 240);    [self addChild:background];    _texture = [[CCTextureCache sharedTextureCache] addImage:@"adventurer.png"];    _spriteSheet = [CCSpriteSheet spriteSheetWithTexture:self.texture capacity:100];    [self addChild:_spriteSheet z:0 tag:kTagSpriteSheet];    self.charArray = [[NSMutableArray alloc] init];      [self schedule:@selector(gameLogic:) interval:1.0f];    return self;}-(void)addAdventurer {    NSLog(@"Add Adventurer");    NSMutableArray *animFrames = [NSMutableArray array];    [animFrames removeAllObjects];    for (int i = 0; i < 9; i++) {        CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:self.texture rect:CGRectMake(i*16, 0, 16, 29) offset:CGPointZero];        [animFrames addObject:frame];    }    Adventurer * adventurer = [[[Adventurer alloc] init] autorelease];    if (adventurer != nil) {        CCSpriteFrame *frame1 = [CCSpriteFrame frameWithTexture:self.texture rect:CGRectMake(0, 0, 19, 29) offset:CGPointZero];        adventurer.charSprite = [CCSprite spriteWithSpriteFrame:frame1];        CGSize s = [[CCDirector sharedDirector] winSize];        int minY = adventurer.charSprite.contentSize.height/2;        int maxY = s.height - adventurer.charSprite.contentSize.height/2;        int rangeY = maxY - minY;        int actualY = (arc4random() % rangeY) + minY;        int minX = -300;        int maxX = 0;        int rangeX = maxX - minX;        int actualX = (arc4random() % rangeX) + minX;        adventurer.charSprite.position = ccp(actualX, actualY);        CCAnimation *animation = [CCAnimation animationWithName:@"walk" delay:0.2f frames:animFrames];        CCAnimate *animate = [CCAnimate actionWithAnimation:animation restoreOriginalFrame:NO];        CCSequence *seq = [CCSequence actions: animate,                           nil];        adventurer.walkAction  = [CCRepeatForever actionWithAction: seq ];                id actionMove = [CCMoveTo actionWithDuration:10.0f position:ccp(s.width + 200,actualY)];        id actionMoveDone = [CCCallFuncND actionWithTarget:self selector:@selector(spriteMoveFinished:data:)data:adventurer];        adventurer.moveAction = [CCSequence actions:actionMove, actionMoveDone, nil];        [adventurer.charSprite runAction:adventurer.walkAction];        [adventurer.charSprite runAction:adventurer.moveAction]; 

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