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メソッド、
1 |
[frameCache addSpriteFramesWithFile:@"md.plist"]; |
EnemyEntity.mのinitWithTypeメソッド、
1 2 |
case EnemyMissile: enemyFrameName = @"enemyMissile.swf/0000"; |
EnemyCache.mのinitメソッドにありました。
1 |
CCSpriteFrame* frame = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:@"enemyMissile.swf/0000"]; |
更に、GameLayer.mから使わなそうな以下をコメントアウトしました。
1 2 3 4 5 |
/* ShipEntity* ship = [ShipEntity ship]; ship.position = CGPointMake([ship contentSize].width / 2, screenSize.height / 2); [self addChild:ship z:0 tag:GameSceneNodeTagShip]; */ |
あと、bulletCacheメソッドでは中身をコメントアウトしてreturn false;を返すようにしました。
1 2 3 4 5 6 7 8 9 |
-(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
1 2 3 4 5 6 7 8 9 |
switch (type) { case EnemyMissile: enemyFrameName = @"enemyMissile.swf/0000"; break; default: [NSException exceptionWithName:@"EnemyEntity Exception" reason:@"unhandled enemy type" userInfo:nil]; } |
EnemyCache.m
1 2 3 4 5 6 7 8 9 10 |
switch (i) { case EnemyMissile: capacity = 10; break; default: [NSException exceptionWithName:@"EnemyCache Exception" reason:@"unhandled enemy type" userInfo:nil]; break; } |
1点、どうしても解決できなかったのがスプライトのコマアニメーション(スプライトフレーム)です。EnemyEntity.mのinitWithTypeメソッドに以下があるとSIGABRTになってしまうので、丸ごとコメントアウトしました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
/* 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を自前のミサイル画像に差し替えることができました!
まだ、コマアニメーションは出来ないし、動きも方向もサンプルのまんま横移動ですが、画像が差し変わったので少しモチベーションが上がってきました。
コマアニメーションは一旦放置して、次は先に簡単にできそうなキャラの動きを調整したいと思います。