您的位置:首页 > 其它

使用TexturePacker 制作动画的贴图 导出在 SpriteKit 中使用.

2014-04-01 12:19 423 查看

作为经常使用的工具, TexturePacker的确是很方便的打包贴图的工具. 打包可以减少DrawCall次数.对于提升性能有很大作用.而且作者很友好,如果是开发阶段使用, 可以申请免费的授权. 当然,如果产品赚了钱都应该买一份正版.SpriteKit是ios7新的特性,为2D游戏开发而做, TexturePacker也推出了一个示范的实现,整合在一起. 工具化,制作流程规范化是趋势. 你out了么.

ios7 SpriteKit 开发者指南.http://upyun.cocimg.com/cocoachina/SpriteKit_PG.pdf

TexturePacker 下载: http://www.codeandweb.com/texturepacker/download

支持的真多啊: Cocos2d SpriteKit Corona SDK Starling Unity3D Flash / AS3CSS / HTML LibGDX AndEngine Moai Cocos2d-X XNA PlayStation® Suite V-Play

SpriteKit Animations and TextureAtlasses

http://www.codeandweb.com/blog/2013/09/23/spritekit-animations-and-textureatlasses

使用TexturePacker 制作动画的贴图 导出在 SpriteKit 中使用.

The main advantages over the pure Xcode solution are

Organizing your sprites in folders

Importing multiple formats such as PNG, PSD, SVG, SWF

Compile time checks for sprite names

Creating animations with a single line of code

纯Xcode的优点: 在目录里自己组织Sprites /可以同时导入各种格式. png psd svg swf / 编译时检查sprite 资源名字 /一行代码完成动画创建.

Let’s start with how to easily create your atlas.

下面就开始示范如何创建 atlas

Create your SpriteKit atlas with TexturePacker

To create a new SpriteKit atlas, simply start TexturePacker and drag & drop the directories containing your sprite images to the Sprites area of TexturePacker. TexturePacker will automatically load and lay out all image files:

拖拽sprites文件夹到 TexturePacker 窗口即可. 导入资源. 如下图.

Select SpriteKit in the Data Format field, and enter a path to which the atlas bundle should be written. Parallel to this .atlasc file TexturePacker generates a .hheader file which contains useful macros for easy SKTexture creation. If you choose the Xcode project directory as output here, the generated header file is automatically found in the include path.

选择导出格式. 设置导出路径以及导出的模板. 推荐导出到Xcode的工程目录里面. 直接就可以include 了.

To use the published sprite sheet in Xcode, drag and drop the .atlasc bundle and the generated .h header file to your Xcode project:

导出后, 需要加入 .atlasc .h 文件到工程里. 方法如下, 拖拽到Xcode 的窗口里.

Xcode asks how the folder should be added. If you create a folder reference , the Xcode project is automatically updated in the future if the altasc bundle changes (e.g. additional sprite sheets are added).

然后, 在对话框里, 选择 create folder references for any added fodlers 以及 确认 add to targets 选中. 这样资源文件才会在打包时包含到App里.

Creating a SKSpriteNode from the texture atlas

演示使用 textureAtlas 创建. SKSpriteNode

Creating a textured sprite is quite easy, just load the texture and use the
SKTexture
object when creating the sprite node:

很简单就是用 SKTexture

texture = [SKTexture textureWithImageNamed:@"Background"];sprite = [SKSpriteNode spriteNodeWithTexture:texture];

The first line loads the sprite—looking for a single sprite in the file system— and if not found searching all sprite sheets available to the application.

The second line creates a sprite object using the specified texture.

Adding compile-time checks to your SpriteKit project

As the texture image is referenced by its file name, typos in its name or a mismatch due to a reorganized texture atlas cannot be detected at compile-time.

因为texture 是一个文件名. 所以没办法在编译时检查某些贴图资源不存在的情况. 毕竟这是逻辑状态. 比如 “button1″ 你可以用不存在的贴图资源创建对象. 只有运行时才会报错. 编译时检查不出来的.

TexturePacker 提供了一个变通的解决方法. 引入了一个头文件 如果你使用了不存在的资源名字. 就会报错了. 当然也需要你使用常量去创建对象. 比如 __BUTTON__ 而不是 “button1“ 后者的话还是会有问题的.

SpriteKit replaces missing images with a dummy graphic which might look strange. Imagine what this would mean for you if it accidently reaches the AppStore…

TexturePacker helps you avoid this: with compile-time checks!

TexturePacker creates a header file together with your atlas. You can simply import it using:

#import "sprites.h"

The file contains all sprite names used in the atlas as a
#define
. It also defines a macro for each texture image which creates the corresponding
SKTexture
object.



#define SPRITES_SPR_BACKGROUND @"Background"#define SPRITES_SPR_CAPGUY_TURN_0001 @"capguy/turn/0001"#define SPRITES_SPR_CAPGUY_TURN_0002 @"capguy/turn/0002"...#define SPRITES_TEX_BACKGROUND [SKTexture textureWithImageNamed:@"Background"]#define SPRITES_TEX_CAPGUY_TURN_0001 [SKTexture textureWithImageNamed:@"capguy/turn/0001"]#define SPRITES_TEX_CAPGUY_TURN_0002 [SKTexture textureWithImageNamed:@"capguy/turn/0002"]

Using these defines, creating a sprite is a 1-liner:

通过定义好的头文件创建 SKSpriteNode 即 Sprite 我们需要的动画精灵.

SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithTexture:SPRITES_TEX_BACKGROUND];

If you now rename the sprite and publish the sprite atlas from TexturePacker, the definition also changes its name. When compiling in Xcode you get a compiler error about a missing sprite.

注意: 如果你修改了定义的名字. 会有编译错误. 需要手动修改成新的动画的名字. (老的被删除了)

Simplifying SpriteKit’s animation handling

Sprites are considered as animation if they end with a number—e.g. img_01 , img_02 , etc. For these an NSArray object with all textures of the animation is defined.



#define SPRITES_ANIM_CAPGUY_TURN @[ \
[SKTexture textureWithImageNamed:@"capguy/turn/0001"], \
[SKTexture textureWithImageNamed:@"capguy/turn/0002"], \
[SKTexture textureWithImageNamed:@"capguy/turn/0003"], \
...
SKSPrite 用数组来管理帧. 如上.

This makes it extremely simple to animate sprites:

SKAction *walk = [SKAction animateWithTextures:SPRITES_ANIM_CAPGUY_WALK timePerFrame:0.033];
[sprite runAction:walk];
初始化一个动画Action 如上. SKAction 是一组动画帧. 代表一个状态. 比如walk.

No more adding single frames, no more worrying about missing animation phases!

Enhancing the animation with additional frames—or removing frames—doesn’t require you change the code at all: TexturePacker always fills in the right frames.

Using SKActions to move the sprite

用SKActions 来移动sprite吧.

For our sample application we use two animations:

walk (left to right)

turn (right to left)

These animations can be created as mentioned above:

SKAction *walk = [SKAction animateWithTextures:SPRITES_ANIM_CAPGUY_WALK timePerFrame:0.033];
SKAction *turn = [SKAction animateWithTextures:SPRITES_ANIM_CAPGUY_TURN timePerFrame:0.033];

Due to the enormous width of the iPad display we have to repeat the animation a few times:

SKAction *walkAnim = [SKAction sequence:@[walk, walk, walk, walk, walk, walk]];
用重复的Action 实现新的组合动画.. 如上.. walk ,walk ...

Note As SpriteKit does not allow repeat actions to be nested, we cannot use [SKAction repeatAction:count:] here, this would conflict with [SKAction repeatActionForever:] , see below. This is why we implement the action as a sequence of walk actions.

注意: 因为 SpriteKit 不允许 重复的actions 被嵌套循环.

In the animation CapGuy walks without moving forward. We need a move action to move the sprite from left to right, and back. The action gets the same duration as the animation itself:

SKAction *moveRight = [SKAction moveToX:900 duration:walkAnim.duration];
SKAction *moveLeft = [SKAction moveToX:100 duration:walkAnim.duration];

We have only an animation with CapGuy walking from left to right, but not in the other direction. So we use a scale action with scaling factor -1 to get a mirrored animation. Another action is needed to set the scaling back to 1:

SKAction *mirrorDirection = [SKAction scaleXTo:-1 y:1 duration:0.0];
SKAction *resetDirection = [SKAction scaleXTo:1 y:1 duration:0.0];

All action which are put into a group are executed in parallel. We are not only adding the walk and move actions to a group, but also the mirror / reset actions. They have a duration of 0 and are executed at the beginning of the group, so their scaling factor has direct impact on the walk / move actions:

所有的action 是并行执行的. 通过在开头加入 mirror/reset 来实现改变方向.

SKAction *walkAndMoveRight = [SKAction group:@[resetDirection, walkAnim, moveRight]];
SKAction *walkAndMoveLeft = [SKAction group:@[mirrorDirection, walkAnim, moveLeft]];

Now we combine walk & turn actions into a sequence, and repeat this sequence forever:

self.sequence =
[SKAction repeatActionForever:[SKAction sequence:@[walkAndMoveRight, turn, walkAndMoveLeft, turn]]];
上面我们把走和转向混合起来.然后一直执行它.

Applying SKAction to multiple SKSpriteNodes

SKAction objects can be used for many sprites in parallel. In our example we want to create a new CapGuy sprite each time the user touches the screen. We have to create a new
SKSpriteNode
only, and run the action on it which we created in the section above:

SKAction作为数据可以给多个SKSPrite对象来使用. 下面的例子实现了 每次点击 新建一个自动走的精灵的.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithTexture:SPRITES_TEX_CAPGUY_WALK_0001];
sprite.position = CGPointMake(100, rand() % 100 + 200);

[sprite runAction:sequence];
[self addChild:sprite];
}

The complete SpriteKit sample

如图,你可以看到很多精灵人物走来走去.

Source code available for download

The source code is available on GitHub . Either clone it using git :

http://www.codeandweb.com/texturepacker

http://www.codeandweb.com/physicseditor

http://twitter.com/CodeAndWeb
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: