ios7 SpriteKit 开发者指南.http://upyun.cocimg.com/cocoachina/SpriteKit_PG.pdfcss
TexturePacker 下载: http://www.codeandweb.com/texturepacker/downloadnode
支持的真多啊: Cocos2d SpriteKit Corona SDK Starling Unity3D Flash / AS3CSS / HTML LibGDX AndEngine Moai Cocos2d-X XNA PlayStation® Suite V-Playios
SpriteKit Animations and TextureAtlassesgit
http://www.codeandweb.com/blog/2013/09/23/spritekit-animations-and-textureatlassesgithub
使用TexturePacker 制做动画的贴图 导出在 SpriteKit 中使用.web
The main advantages over the pure Xcode solution are数组
Organizing your sprites in foldersruby
Importing multiple formats such as PNG, PSD, SVG, SWFbash
Compile time checks for sprite namesapp
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
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里.
演示使用 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.
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.
注意: 若是你修改了定义的名字. 会有编译错误. 须要手动修改为新的动画的名字. (老的被删除了)
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.
用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]]]; 上面咱们把走和转向混合起来.而后一直执行它.
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 source code is available on GitHub . Either clone it using git :
http://www.codeandweb.com/texturepacker