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

来源:互联网 发布:细说php第一版 pdf 编辑:程序博客网 时间:2024/05/18 01:43

免责声明:本博客的所有原创文章,均有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
  1. #import <GameKit/GameKit.h>  
  2. #import "cocos2d.h"  
  3.   
  4. @interface HelloWorldLayer : CCLayerColor  
  5. {  
  6.     CCSprite * _bear;  
  7.     CCAction * _walkAction;  
  8.     CCAction * _moveAction;  
  9. }  
  10.   
  11. @property(nonatomic,retain)CCSprite * bear;  
  12. @property(nonatomic,retain)CCAction * walkAction;  
  13. @property(nonatomic,retain)CCAction * moveAction;  
  14.   
  15. +(CCScene *) scene;  
  16.   
  17. @end  

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

[cpp] view plaincopy
  1. @synthesize bear = _bear;  
  2. @synthesize walkAction = _walkAction;  
  3. @synthesize moveAction = _moveAction;  

dealloc方法里面添加:

[cpp] view plaincopy
  1. self.bear = nil;  
  2. self.walkAction = nil;  
  3. self.moveAction = nil;  
1、缓冲Sprite帧和纹理

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

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

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

[cpp] view plaincopy
  1. CCSpriteBatchNode * spriteSheet = [CCSpriteBatchNode batchNodeWithFile:@"xiaobing.png"];  
  2. [self addChild:spriteSheet];//将此CCSpriteBatchNode添加到场景中  

3、收集帧列表:

[cpp] view plaincopy
  1. //为了创建一系列的动画帧,我们简单地遍历我们的图片名字(它们是按照 xiaobing001.png -> xiaobing008.png 的方式命名的),然后使用共享的CCSpriteFrameCache来获得每一个动画帧。  
  2.        //记住,它们已经在缓存里了,因为我们前面调用了addSpriteFramesWithFile方法。  
  3.        NSMutableArray * walkAnimFrames = [NSMutableArray array];  
  4.        for (int i = 1; i <= 8; i ++)  
  5.        {  
  6.              
  7.            [walkAnimFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"xiaobing%.3d.png",i]]];  
  8.        }  
  9.          
  10.        //创建动画对象,我们通过传入sprite帧列表来创建一个CCAnimation对象,并且制定动画的播放速度 0.1秒就是动画播放的时间间隔  
  11.        CCAnimation *walkAnim = [CCAnimation animationWithSpriteFrames:walkAnimFrames delay:0.1f];  
  12.          
  13.        CGSize winSize = [CCDirector sharedDirector].winSize;  
  14.        //首先通过spriteframe来创建一个sprite  
  15.        self.bear = [CCSprite spriteWithSpriteFrameName:@"xiaobing001.png"];   
  16.        //将小兵放在屏幕的中央 然后循环播放所有的动画帧  
  17.        _bear.position = ccp(winSize.width/2, winSize.height/2);  
  18.          
  19.        self.walkAction = [CCRepeatForever actionWithAction:[CCAnimate actionWithAnimation:walkAnim]];  
  20.        //[_bear runAction:_walkAction];  
  21.          
  22.        [spriteSheet addChild:_bear];  

4、响应触摸事件:

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

[cpp] view plaincopy
  1. self.isTouchEnabled = YES;  

[cpp] view plaincopy
  1. -(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event  
  2. {  
  3.     NSLog(@"触摸开始时!");  
  4. }  
  5.   
  6. -(void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
  7. {  
  8.     [_bear stopAllActions];  
  9.       
  10.     //把touch点转换成我们要使用的局部坐标系点  
  11.     UITouch * touch = [touches anyObject];  
  12.       
  13.     NSLog(@"触摸结束后,事件响应中......");  
  14.       
  15.     CGPoint touchLocation = [touch locationInView:[touch view]];  
  16.     touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];  
  17.       
  18.     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
  1.       
  2.     float bearVelocity = 480.0/8.0;//设置熊的移动速度:假设熊要花3秒钟时间才能从iphone屏幕(480个像素宽的一头移动到另一头。因此,简单地用480个像素除以3秒  
  3.     CGPoint moveDifference = ccpSub(touchLocation, _bear.position);//计算X轴和Y轴的移动量  
  4.     //计算出熊相当于x轴和y轴移动了多远。我们简单地使用touch坐标减去熊当前的坐标。这里使用了cocos2d的一个帮助函数ccpSub来实现这个功能  
  5.       
  6.     float distanceToMove = ccpLength(moveDifference);  
  7.     //计算出熊实际移动的距离(欧几里德距离)。cocos2d里面也提供了一个帮助函数来做这个事情,这个函数就是ccpLength,用来求一个向量的长度。  
  8.       
  9.     float  moveDuration = distanceToMove/bearVelocity;  
  10.   
  11.     self.moveAction = [CCSequence actions:[CCMoveTo actionWithDuration:moveDuration position:touchLocation],   
  12.                                           [CCCallFunc actionWithTarget:self selector:@selector(bearMoveEnded)],   
  13.                                            nil];     
  14.       
  15.     [_bear runAction:_walkAction];  
  16.     [_bear runAction:_moveAction];  
  17. }  
  18.   
  19. -(void) bearMoveEnded  
  20. {  
  21.     [_bear stopAction:_walkAction];  
  22. }  

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

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

项目源代码下载

0 0
原创粉丝点击