使用TexturePacker 制作动画的贴图 导出在 SpriteKit 中使用.SpriteKit Animations and TextureAtlasses,Use TexturePacker.

作为经常使用的工具, 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 / AS3 CSS / HTMLLibGDX 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 .h header 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 altascbundle 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_01img_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 walkturn 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:

Read More

Unity Network Programming Useful Link

Tutorials on Photon, Unity and Networking

List of third party tutorials on Photon Cloud, Photon Server, Unity 3D and Networking

Photon Tutorials

General Networking Tutorials

Unity Networking Tutorials

Unity Tutorials

  • Tutorials section on Unity website, currently there are beginner’s tutorials only, but more are coming
  • Collection of video lessons for beginner and intermediate Unity developers, includes challenges and examples
  • Another collection of various Unity tutorials from Unity Cookie
  • Video tutorials on various Unity 3 topics from Technicat
  • Big list of tutorials on Unity, including game making, labs and exams from Walker Boys studio
  • UnityGems, tutorials on Basics, AI, Shaders and Finite State Machines written by contributors to Unity Answers and Unity Forums

Read More

被ios7bug,基于api的接口都是脆弱的.

此次ios7发布. 总体感觉,比ios6 ios5升级时颠覆感要强烈很多.

进而带来的就是老项目代码升级问题.

显然 作为开发应用的支持, apple 做了功课. 比如分辨率 透明statusbar处理等, 挖掘一下以后, app开发应该是可以无痛升级的. 核心代码不用改.

而游戏项目, 我们用了cocos2dx 的游戏就有点悲催, 会在ios7上闪退.  track了一番, 最后是 CCFileUtils 取路径的函数的bug. 真不知道ios7改动了啥. getfullpath 需要传入一个存在的文件名.

已经上架了的project,  至少还得重新patch compile 再提交一次..   用了cocos2dx 这么久了也有些要吐槽的, 接口差异变化挺大. 文件名改动. 换位置..各种… 冷不丁要从一旧版本升级到新版,还真有些小折腾.

跑题了, 回到标题.  ios7升级是个新的知识点. 初期没有太多可以google到的. 所以要么自己动手,要么等待..   没有项目压力的话, 还好. 否则, 你想象一下.  而基于ios api 的 api 就有可能随着底层变更而变得有些bug. 是被bug的.

而Apple显然也没进行额外的测试和支持?  只是保证了大多数情况下是ok的.

对于处理升级中遇到的问题,  其实, 如果平日你积累了人脉. 问一圈下来,大概也就有数了. 大方向不会错.

我总结如下

xcode4.6 编译也是可以跑在 ios7上的. 所以最快的方式先修了闪退的bug.  然后更新.

xcode5编译还有一些诡异的问题等着我们.   暂时可以放一放. 慢慢过渡到2.2.0 纯ios7. 新项目应该用新版本.

还有一个伴随的扰乱视线的bug,   Project里面资源文件夹  蓝色和黄色图标的区别是在 App 包里是否创建同样的目录.. 真蛋疼.    黄色的 你用了带目录的路径就找不到文件…

Read More