您的位置:首页 > 移动开发 > Cocos引擎

如何在cocos2d里面用TexturePacker制作可移动的炮炮兵动画

2014-03-05 10:37 591 查看
免责声明:本博客的所有原创文章,均有time_anime精心写作,供学习交流使用,切勿进行商业传播。

同时,转载请不要移除本声明!

本文介绍如何在cocos2d里面使用SpriteSheet(精灵表单)和TexturePacker工具制作动画(Animation)。如何对精灵表单不清楚的可以参见我的这篇博文

在这个教程里,我将向大家展示如何用cocos2d来制作一只炮炮兵扭动的动画。同时,我会使用spritesheet来使动画运行效率更高,还有如何让用户鼠标点击决定炮炮兵扭腰的行走方向。

首先我们新建一个cocos2d工程,命名为PaoPaoBing。嘎嘎!

如果你从来没有使用过spritesheet,你可以把它看作是一张巨大的图片,你可以把许许多多的sprite放进去。与spritesheet对应的,还有一个plist文件,这个文件指定了每个独立的sprite在这张“大图”里面的位置和大小,当你在代码之间需要使用这个sprite的时候,就可以很方面地使用plist文件中的这些信息来获取sprite。为什么这会提高效率呢?因为cocos2d对它进行了优化!如果你使用spritesheet来获取sprite,那么当场景中有许多sprite的时候,如果这些sprite共享一个spritesheet,那么cocos2d就会使用一次OpenGL
ES调用来渲染这些sprite。但是,如果是单个的sprite的话,那么就会有N次OpenGL ES call,这个代价是相当昂贵的。简而言之--使用spritesheet会更快,尤其是当你有很多的sprite的时候!(使用spritesheet还可以减少游戏占用的内存大小。

由于要使用spritesheet,你当然可以手工用图片编辑器来创建,然后创建一个plist指定每一个sprite在spritesheet里面的位置和大小。然后,那样将会是一个非常SB的行为,因为我们发现一个好的工具--TexturePacker,它可以帮助我们自动生成这一切!

我用的PJ版本,MAC和windows都有,而且功能界面基本差不多。下面来研究下这个工具的使用。

首先,我们将8个动画帧添加到这个工具里面去。



软件自动给你将8个图片排列到一个image上面。然后点击工具栏上面的Publish按钮,就生成了合成后的png和plist文件。直接将这两个文件拖到项目的资源文件夹中。记得选中Copy。

首先让我们在HelloWorldLayer里面增加一些属性吧。

[cpp] view
plaincopy

#import <GameKit/GameKit.h>  

#import "cocos2d.h"  

  

@interface HelloWorldLayer : CCLayerColor  

{  

    CCSprite * _bear;  

    CCAction * _walkAction;  

    CCAction * _moveAction;  

}  

  

@property(nonatomic,retain)CCSprite * bear;  

@property(nonatomic,retain)CCAction * walkAction;  

@property(nonatomic,retain)CCAction * moveAction;  

  

+(CCScene *) scene;  

  

@end  

HelloWorldLayer实现里面添加如下代码:

[cpp] view
plaincopy

@synthesize bear = _bear;  

@synthesize walkAction = _walkAction;  

@synthesize moveAction = _moveAction;  

dealloc方法里面添加:

[cpp] view
plaincopy

self.bear = nil;  

self.walkAction = nil;  

self.moveAction = nil;  

1、缓冲Sprite帧和纹理

首先,调用CCSpriteFrameCache的addSpriteFramesWithFile方法,然后把TexturePacker生成的plist文件当作参数传进去。这个方法做了以下几件事:

寻找工程目录下面和输入的参数名字一样,但是后缀是.png的图片文件。然后把这个文件加入到共享的CCTextureCache中。(这我们这个例子中,就是加载xiaobing.png)
解析plist文件,追踪所有的sprite在spritesheet中的位置,内部使用CCSpriteFrame对象来追踪这些信息。

[cpp] view
plaincopy

[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"xiaobing.plist"];  

2、创建一个精灵批处理结点:

[cpp] view
plaincopy

CCSpriteBatchNode * spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"xiaobing.png"];  

[self addChild:spriteSheet];//将此CCSpriteBatchNode添加到场景中  

3、收集帧列表:

[cpp] view
plaincopy

//为了创建一系列的动画帧,我们简单地遍历我们的图片名字(它们是按照 xiaobing001.png -> xiaobing008.png 的方式命名的),然后使用共享的CCSpriteFrameCache来获得每一个动画帧。  

       //记住,它们已经在缓存里了,因为我们前面调用了addSpriteFramesWithFile方法。  

       NSMutableArray * walkAnimFrames = [NSMutableArray array];  

       for (int i = 1; i <= 8; i ++)  

       {  

             

           [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"xiaobing%.3d.png",i]]];  

       }  

         

       //创建动画对象,我们通过传入sprite帧列表来创建一个CCAnimation对象,并且制定动画的播放速度 0.1秒就是动画播放的时间间隔  

       CCAnimation *walkAnim = [CCAnimation animationWithSpriteFrames:walkAnimFrames delay:0.1f];  

         

       CGSize winSize = [CCDirector sharedDirector].winSize;  

       //首先通过spriteframe来创建一个sprite  

       self.bear = [CCSprite spriteWithSpriteFrameName:@"xiaobing001.png"];   

       //将小兵放在屏幕的中央 然后循环播放所有的动画帧  

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

         

       self.walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim]];  

       //[_bear runAction:_walkAction];  

         

       [spriteSheet addChild:_bear];  

4、响应触摸事件:

首先在init方法中添加如下代码:启用touch功能。

[cpp] view
plaincopy

self.isTouchEnabled = YES;  

[cpp] view
plaincopy

-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  

{  

    NSLog(@"触摸开始时!");  

}  

  

-(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  

{  

    [_bear stopAllActions];  

      

    //把touch点转换成我们要使用的局部坐标系点  

    UITouch * touch = [touches anyObject];  

      

    NSLog(@"触摸结束后,事件响应中......");  

      

    CGPoint touchLocation = [touch locationInView:[touch view]];  

    touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];  

      

    touchLocation = [self convertToNodeSpace:touchLocation]; //<span style="font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px; line-height: 20px; ">把touch点转换成我们要使用的局部坐标系点。</span>  

[cpp] view
plaincopy

      

    float bearVelocity = 480.0/8.0;//设置熊的移动速度:假设熊要花3秒钟时间才能从iphone屏幕(480个像素宽的一头移动到另一头。因此,简单地用480个像素除以3秒  

    CGPoint moveDifference = ccpSub(touchLocation, _bear.position);//计算X轴和Y轴的移动量  

    //计算出熊相当于x轴和y轴移动了多远。我们简单地使用touch坐标减去熊当前的坐标。这里使用了cocos2d的一个帮助函数ccpSub来实现这个功能  

      

    float distanceToMove = ccpLength(moveDifference);  

    //计算出熊实际移动的距离(欧几里德距离)。cocos2d里面也提供了一个帮助函数来做这个事情,这个函数就是ccpLength,用来求一个向量的长度。  

      

    float  moveDuration = distanceToMove/bearVelocity;  

  

    self.moveAction = [CCSequence actions:[CCMoveTo actionWithDuration:moveDuration position:touchLocation],   

                                          [CCCallFunc actionWithTarget:self selector:@selector(bearMoveEnded)],   

                                           nil];     

      

    [_bear runAction:_walkAction];  

    [_bear runAction:_moveAction];  

}  

  

-(void) bearMoveEnded  

{  

    [_bear stopAction:_walkAction];  

}  

这种响应方式叫做标准触摸响应。以后的文章中专门对触摸进行讲解。

文章里面有一些问题没讲清楚,时间比较匆忙,如果大家有不懂的话评论给我。我会在12小时内回复。

项目源代码下载
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: