自キャラを固定配置する

kobold2dのサンプルに入っていたParallax-Side-Scrollerを改造して自分のゲームにしている件です。
前回、元々横方向だった敵キャラの移動を縦方向にしました
今回は、自キャラの1つである都市と基地を設置します。

Xcodeで作業を始める前に、都市と基地の絵をTexture Packerで読み込みます。

130512 0003
Texture Packerは、画像ソースを追加できます。
前回作成した.tpsファイルを開き、都市と基地のswfをTexture PackerのSprites枠へドラッグアンドドロップします。すると、即座にスプライトシートを広げてくれるので、Publishして.plistファイルと.pvr.cczファイルを生成します。
あとは、XcodeのResourcesへAdd Files to…してスプライトシートの差し替えします。ちなみに、Add Files toする前に、元の.plistファイルと.pvr.cczファイルを消さないと「Multiple errors occurred while copying the files.」というエラーが出て差し替えできません。

スプライトシートを追加したら、EnemyCacheとEnemyEntityの.hと.mをコピーしてそれぞれBaseCacheとBaseEntityとしました(ファイルはFinderでコピーして、XcodeへAdd Files toしました)。
あとは、Enemyのものをパクれば簡単だ!、、、と思っていたのですが、現実はそんなに甘くありませんでした。

まず、「Enemy」と付いたものは、コメントアウトも含めて片っ端から「Base」に変えました。
それから、キャラクターの設置を一先ず都市だけで試してみることにしました。

こちらはBaseEntity.hでの定義です。

EnemyEntity.mでenemyMissile.swfだった画像は、スプライトシートに追加したcity.swfをBaseEntity.mへ読み込みます。
弾を出さなかったり、フレームアニメをコメントアウトしたのは、EnemyEntity.mと同じです。
あと、試しで表示させたかったので、spawnメソッドではxとyの座標に固定値を入れました。

次に、BaseCache.mです。

こちらのinitメソッドでも、spriteFrameByNameで読み込む画像をenemyMissile.swfからcity.swfへ差し替えます。

都市を1個だけ試しに表示できれば良いのでcapacityは1にしておきます。

多分、これで都市が表示されるハズ!っとRunしてみましたが、、、表示されませんでした。
ここで少し躓きました。BaseEntity.mのinitWithTypeメソッドにあるStandardMoveComponentのaddChildを削除しなければならなかったのです。

StandardMoveComponentクラスは何をしているかと言うと、読んだ親クラスをひたすら移動させるようにされていました。
都市は動かないので、このクラスの呼び出しは不要という訳です。

130509 0001
表示されたのが、この画面です。
ヤッター!都市が1つ表示されただけですが、嬉しいの何のって。こうやってモチベーションを上げていく訳です。

さて、今度はいよいよ都市を並べて行きます。画面が狭いので、札幌、東京、大阪、福岡の4つを表示することにしました。
で、どこで都市を生成しようか悩んだのですが、まずBaseCache.mのinitBasesメドッド内の以下で試してみました。

baseをaddChildしているので、その際にxとy座標で移動させれば良いかと考えた訳です。
そこで、initBasesから呼べるように、同じBaseCache.mの直下にbase_pointという配列を置きました。

本当は、CCDictionaryとか使ってみたかったのですが、使い方がまだよく分からないので、1作目のとけいであそぶに使った多次元配列を使いました。
各都市の座標を格納する配列を定義します。最初は適当な数値で試し、後で画像ソフトを使って位置を測り直しました。
さっき1にしたcapacityも4にしておきます。

さて、これで上手く行くはずとRunしましたが、何故か表示される都市が最初の配列の1つだけしか表示されません。。。
また、ホントやめようかと思うくらい躓きました。そしてイロイロと試しまくりました。
結局、何で1つしか表示されないのかは分かりませんでしたが、BaseEntityクラスでbaseWithTypeをコールする時に、iだけじゃなくてjも引数で渡して行くように変更しました。

そのため、BaseEntityのクラスメソッドであるbaseWithTypeでjが受け取れるように変更しました。

BaseEntity.hの宣言を変更しました。

こちらはBaseEntity.mのbaseWithTypeの実装です。
当然、ここでコールしているinitWithTypeメソッドにもjをbaseIDとして渡すので、、、

initWithTypeも引数を追加するように変更しなければなりません。
そして、initWithType内からspawnメソッドをコールするので、、、

その際にjをbaseIDとして渡すようにしました。
元々コールしてたinitSpawnFrequencyメソッドではなく、spawnメソッドを直接コールするようにしたのは、基地は1度出現したら何度も出直さないからです。
(多分、initSpawnFrequencyメソッドは、出現頻度を管理しているんだと思います)

やっと、都市のx,y座標を指定できる場所を決めることができました。バケツリレー式に渡されたBaseCacheのinitBasesのj(baseID)をspawnメソッドで都市の座標を決めるのに使います。
もちろん、最初にBaseCache.mに置いていたbase_point配列は、spawnメソッドで使うためにBaseEntity.mの直下へ移動しました。

130512 0002
これでやっとこさ、都市を並べて表示できました!
う〜ん感動的ですが、時間がかかりすぎです。

130514 0001
で、これって3.5インチの画面で見たらどうなるんだろう?という素朴な疑問から、iPhoneシミュレーターを3.5インチにしたところ、、、。
そりゃそうですね。見た目の背景は位置を変えましたが、絶対座標は相変わらず左下がx=0,y=0なワケですから。。。
次は、3.5インチ(iPhone4s以下)と4インチ(iPhone5以降)で絶対座標が変わるようにできないか検討してみたいと思います。