kobold2dのサンプルに入っていたParallax-Side-Scrollerを改造して自分のゲームにしている件です。
前回、自キャラの出し分けをしました。
今回は、敵キャラを自キャラへ誘導します。
今作っているゲーム自体は、過去にFlashで作ったことがあるので、ロジックだけ抜き出せば済むので今回は簡単と思っていました。
誘導させるところだけに関してはその通りだったのですが、別のところでドツボにハマりました。
まず、EnemyEntity.mの動きを変えるべく、EnemyEntity.mから呼んでいるStandardMoveComponentクラスのupdateメソッドを変えることにしました。
1 2 3 4 5 |
self.parent.position =ccp(myPos.x + (targetX - myPos.x) * 0.03, myPos.y -ySpeed); if (abs(targetX - myPos.x)<1) {//誘導完了 self.parent.position =ccp(targetX, self.parent.position.y); } |
肝はここです。x軸で自キャラのx座標へ誘導します。よく、FlashのActionScriptサンプルにある「マウス追随ムービークリップ」のパクリです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
-(void) update:(ccTime)delta {//移動の管理 if (self.visible) { NSAssert([self isKindOfClass:[Entity class]], @"node is not a Entity"); CGFloat targetX =200; self.position =ccp(self.position.x + (targetX - self.position.x) * 0.03, self.position.y -ySpeed); if (abs(targetX - self.position.x)<1) {//誘導完了 self.position =ccp(targetX, self.position.y); } CGRect screenRect = [GameLayer screenRect]; if (self.position.y < -100) {//画面下端まで行ったら self.position =ccp(CCRANDOM_0_1() * (screenRect.size.width), screenRect.size.height); } } } |
ただ、サンプルのParallax-Side-Scrollerのように全敵キャラが同じ動きをすれば1つの別クラスで動きを制御するのは効率が良いですが、敵キャラごとに動きを変える予定なのでStandardMoveComponentクラスの内容をEnemyEntityへ統合しました。
自キャラを狙おうとすると、自キャラを蓄えたCCArrayから座標を拾う必要があって面倒なので、テストは座標を決め打ちにしました。
また、敵キャラが何発も動くと不具合の時の現象が掴みづらいので、EnemyMissileのcapacityを1にして1発だけ動くようにしました。
で、これで当たるハズとiPhoneシミュレーターをRunしてみたところ、、、
東京そっちちゃうよ〜!!まさかの誘導失敗。。。
そんなハズは無い、座標が間違ってるのかということでEnemyEntityにNSLogを仕掛けてposition.xを調べたりしましたが、座標に間違いはありませんでした。また、position.yで0にしても、画面下端より少し上に来てしまいます。
EnemyEntityの座標がおかしいことが分かりました。
ちなみに、positionをNSLogで調べるには、「NSLog(@”position:%@”, NSStringFromCGPoint(self.position));」とするそうです。
ここから久しぶりにハマりました。
BaseEntityは問題なく座標どおりなのに、EnemyEntityだけが座標が狂っている。ということで、まずはEnemyEntityとEnemyCacheクラスの何処かに問題があると疑い、上手く行っているBaseEntityとBaseCacheのソースコードと徹底的に比較してみました。
しかし、どこにも問題がありません。
次に疑ったのは、config.luaやInfo.plistです。EnemyEntityのxを0にすると、画面の外にはみ出すので、interface orientationがlandscapeになってるのではないかと思ったからです。しかし、ここも問題ありませんでした。
最後に疑ったのが、md.plistです。でも、これはスプライトシートの中の座標なので、関係ありませんでした。
あと、Texture Packerでスプライトシートシートをパブリッシュする設定がおかしいのではないかも疑いました。おかげで、Texture Packerには様々なレイアウトでスプライトシートを生成できることを知りました。
でも、これも直接的には関係ありませんでした。と、その時、あることが浮かびました。座標が正しいBaseEntityのスプライトをEnemyEntityのものに変えたらどうなるか?
で、試したところ、、、
予想的中でした。見事に座標がズレました。いや、座標がズレてるのではなく、スプライトシートの画像がズレていることが分かりました。逆に、EnemyEntityのスプライトをBaseEntityで使うと、正しい位置で表示されました。
ということで、犯人はスプライトシートでした。ここまで分かるのに、数日を要しました。また今回もプロジェクト中止かとも考えてしまいました。
試しにpngで敵キャラの画像を作り、それを今までのTexture Packerのデータに追加してパブリッシュしたところ、、、
問題なく正しい位置に表示されました!
つまり、Texture Packerでswfを基にスプライトシートをパブリッシュすると、今回のようにおかしいものも生成されてしまうということのようです。
東京が集中狙い状態ですね。
最初は余裕で出来ると考えていましたが、思わぬ所で罠にハマってしまい、無駄に時間を費やしてしまいました。
次は、自キャラの位置をCCArrayからランダムに取り出して、敵キャラにロックオンさせます。