现在的位置: 首页 > 综合 > 正文

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

2013年12月08日 ⁄ 综合 ⁄ 共 4213字 ⁄ 字号 评论关闭

免责声明:本博客的所有原创文章,均有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里面增加一些属性吧。

#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实现里面添加如下代码:

@synthesize bear = _bear;
@synthesize walkAction = _walkAction;
@synthesize moveAction = _moveAction;

dealloc方法里面添加:

self.bear = nil;
self.walkAction = nil;
self.moveAction = nil;

1、缓冲Sprite帧和纹理

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

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

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

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

3、收集帧列表:

 //为了创建一系列的动画帧,我们简单地遍历我们的图片名字(它们是按照 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功能。

 self.isTouchEnabled = YES;

-(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]; //把touch点转换成我们要使用的局部坐标系点。
    
    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小时内回复。

项目源代码下载

抱歉!评论已关闭.