kobold2dのサンプルに入っていたParallax-Side-Scrollerを改造して自分のゲームにしている件です。
前回、Texture Packerのインストールまで進みました。
今回、実際にTexture Packerを使ってスプライトシートを作り、kobold2dで作っているゲームのプロジェクトにAddしていきます。
まず、Texture Packerの使い方ですが、凄く詳細に書かれたページ(「ブレイブソフト 技術研究Blog」)があるのでそちらを参照しました。
また、Flashでコマアニメのswfを作ってTexture Packerで書き出す方法が、Texture PackerのTutorialsに掲載されていたので参考にしました。
今回作ろうとしているゲームの元ネタは、過去にFlashで作ったものだったので、swfが読み込めるのはとっても便利です。

Texture Packer自体の作業は簡単でした。swfファイルもpngなどと同様にドラッグアンドドロップでSpritesへボトっとやるだけです。自動的に中のアニメーションをスプライトシートへ展開してくれます。
上記のswfで書き出すチュートリアルの1〜3をやるだけで、スプライトシート(.pvr.cczと.plistのセット)がパブリッシュできました。
<追記>——
この後、swfを基にしたスプライトシートのパブリッシュが不具合を引き起こす問題に直面しました。使用には注意が必要です。
</追記>——

赤丸は、今回設定した箇所です。緑丸は好みで変更ですね。デフォルトでも良いと思います。
swfファイルで生成した際に注意すべき点は、生成されるスプライトフレームの名前が「swfファイル名+/XXXX(0000から始まる数字)」となってplistファイルへ記載される点です。全てのアニメーションを1つのswfでやろうとすると、XXXXの部分でキャラを見分けないと行けないので、Xcodeで呼び出す際に不便です。
Texture Packerではspritesの名前を変えられないようなので、Flashでキャラやキャラのアニメーション毎にシーンを分け、Flashのシーンプレビューでswfファイルをバラバラに書き出すか、flaファイルで分けるのが良さそうですね。

あと、Retina対応のスプライトシートを作る際には、Data fileで名前を付ける際に「-hd」として名前を付けないと、Retina対応の.pvr.cczファイルと.plistファイルのセットがパブリッシュされません。

この後、「AutoSD」という歯車みたいなボタンを押して、開いたウィンドウでそのまま「Apply」をクリックします。
<追記>
Texture Packerでスプライトシートを作ったら、「Save」で保存しておくと良いです。後で、画像を追加したい時に便利です。保存すると.tpsというファイルが生成されます。
</追記>
躓いたのは、kobold2dのサンプル「Parallax-Side-Scroller」で、UFO(monster-a.png)のキャラを自前のキャラ画像と差し替える時でした。

まず、Texture Packerで作った2つずつの.pvr.cczと.plistを、Xcodeのプロジェクトに「Add Files to “”」するのは問題ありませんでした。
次に、game-art.plistやmonster-a.pngとそのフレームに関する部分を、自前のplistやフレームに差し替えました。GameLayer.mのinitメソッド、
[frameCache addSpriteFramesWithFile:@"md.plist"];
EnemyEntity.mのinitWithTypeメソッド、
case EnemyMissile: enemyFrameName = @"enemyMissile.swf/0000";
EnemyCache.mのinitメソッドにありました。
CCSpriteFrame* frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"enemyMissile.swf/0000"];
更に、GameLayer.mから使わなそうな以下をコメントアウトしました。
/* ShipEntity* ship = [ShipEntity ship]; ship.position = CGPointMake([ship contentSize].width / 2, screenSize.height / 2); [self addChild:ship z:0 tag:GameSceneNodeTagShip]; */
あと、bulletCacheメソッドでは中身をコメントアウトしてreturn false;を返すようにしました。
-(BulletCache*) bulletCache
{
/*
CCNode* node = [self getChildByTag:GameSceneNodeTagBulletCache];
NSAssert([node isKindOfClass:[BulletCache class]], @"not a BulletCache");
return (BulletCache*)node;
*/
return false;
}
あと、EnemyEntity.mのinitWithTypeとEnemyCache.mのinitにあるswitch文では、自前のキャラをcaseに追加して、それ以外は消しました。
EnemyEntity.m
switch (type)
{
case EnemyMissile:
enemyFrameName = @"enemyMissile.swf/0000";
break;
default:
[NSException exceptionWithName:@"EnemyEntity Exception" reason:@"unhandled enemy type" userInfo:nil];
}
EnemyCache.m
switch (i)
{
case EnemyMissile:
capacity = 10;
break;
default:
[NSException exceptionWithName:@"EnemyCache Exception" reason:@"unhandled enemy type" userInfo:nil];
break;
}
1点、どうしても解決できなかったのがスプライトのコマアニメーション(スプライトフレーム)です。EnemyEntity.mのinitWithTypeメソッドに以下があるとSIGABRTになってしまうので、丸ごとコメントアウトしました。
/*
if (type == EnemyMissile)
{
// create an animation object from all the sprite animation frames
float delay = CCRANDOM_0_1() * 0.04f + 0.1f;
CCAnimation* anim = [CCAnimation animationWithFrames:@"enemyMissile.swf-anim" frameCount:2 delay:delay];
// run the animation by using the CCAnimate action
CCAnimate* animate = [CCAnimate actionWithAnimation:anim];
CCRepeatForever* repeat = [CCRepeatForever actionWithAction:animate];
[self runAction:repeat];
}
*/

ここまでやって、何とかUFOを自前のミサイル画像に差し替えることができました!
まだ、コマアニメーションは出来ないし、動きも方向もサンプルのまんま横移動ですが、画像が差し変わったので少しモチベーションが上がってきました。
コマアニメーションは一旦放置して、次は先に簡単にできそうなキャラの動きを調整したいと思います。