kobold2dのサンプルに入っていたParallax-Side-Scrollerを改造して自分のゲームにしている件です。
前回、敵キャラが自キャラをランダムにロックオンする仕組みを作りました。
今回は、敵キャラによる自キャラ(固定目標)への当たり判定の仕組みを作ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
-(void) update:(ccTime)delta {//移動の管理 if (self.visible) { NSAssert([self isKindOfClass:[Entity class]], @"node is not a Entity"); targetBaseX =myTarget.position.x; targetBaseY =myTarget.position.y; targetBaseH =myTarget.contentSize.height*0.25; targetBaseW =myTarget.contentSize.width*0.25; self.position =ccp(self.position.x + (targetBaseX - self.position.x) * xSpeed, self.position.y -ySpeed); if (isDestroy ==NO) { if (targetBaseY +targetBaseH*0.5 > self.position.y) {//当たり判定Y if (abs(self.position.x - targetBaseX)<targetBaseW*0.5) {//当たり判定X NSLog(@"missile:%d:Hit!",myTarget.myID); [myTarget gotHit]; isDestroy =YES; self.visible =NO; //[self gotHit]; } } } if (self.position.y < -100) {//画面下端まで行ったら [self reset]; } } } |
今回は、相手(自キャラの都市や基地)が固定ということで、簡単な当たり判定にしました。
場所は、EnemyEntity.mのupdateメソッドに書きました。
1 2 |
if (targetBaseY +targetBaseH*0.5 > self.position.y) {//当たり判定Y if (abs(self.position.x - targetBaseX)<targetBaseW*0.5) {//当たり判定X |
自キャラのX,Y座標を見て、高さと幅を加味しています。
これに適合したら、自分と相手を消します。
1 2 |
targetBaseH =myTarget.contentSize.height*0.25; targetBaseW =myTarget.contentSize.width*0.25; |
ここで躓いたのは、自キャラの大きさの取得方法が分からなかったことです。
contentSizeというプロパティで取得できるようなのですが、そのままだと4倍くらい大きかったので、1/4にして使いました。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
-(void) targeting { //インスタンス生成 baseCache =[[BaseCache alloc] init]; myTarget =[[BaseEntity alloc] init]; //ターゲットをランダムに取得 int length =baseCache.friendlies.count; srand(time(nil));//乱数初期化 int myTargetID = rand()%length;//0~Xまでの間で乱数を発生 myTarget =[baseCache.friendlies objectAtIndex:myTargetID]; } |
自キャラと敵キャラが衝突したり、敵キャラが自キャラに当たらなかった場合に、目標設定をし直すために目標設定用のコードをEnemyEntity.mのspawnメソッドから外に出し、targetingメソッドとしました。
1 2 3 4 5 6 7 8 |
-(void) reset { isDestroy =NO; [self targeting]; CGRect screenRect = [GameLayer screenRect]; self.position =ccp(CCRANDOM_0_1() * (screenRect.size.width), screenRect.size.height); self.visible =YES; } |
また、敵キャラが自キャラに当たらなかった場合は上空から出直すので、resetというメソッドに処理をまとめました。
1 2 3 4 5 6 |
-(void) gotHit { _isDestroyed =YES; NSLog(@"destroyed:%d",_myID); self.visible = NO; } |
当てられた側の自キャラの処理は単純です。BaseEntity.mのgotHitメソッドを設置しました。
デバッガで当たった瞬間にブレークポイントを仕掛けて確認します。
分かり易くするよう、敵キャラは1発にして確認しました。
NSLogで書いた「missile:2:Hit!」がログに表示されています。
衝突判定の検出が成功です!
しかし、この後に自キャラを消すところで完全に行き止まりになりました。
BaseEntity.mのgotHitメソッドにself.visible =NO;として、衝突したら姿を消すように指定したのですが消えません。。。
またもや、完全に行き止まりです。。。
kobold2dのサンプル「Parallax-Side-Scroller」を改造して自分のゲームにするという方法で進めてきましたが、既に2ヶ月近く経ってしまいました。1日平均1〜2時間程度しか制作が進められないとは言え、壁にぶつかっては1〜2週間かかってしまうのでは、年内にアプリが完成しそうにありません。
1番の問題は、ベースにしているサンプルコードを何となく分かった気で進んで行くと、ぶつかった時の壁が高くなって解析にかかる時間が増えていくことです。
やっぱりここは無理せず、1度制作済みで仕組みがある程度分かり、困った時でも解説が見られるサンプルコードをベースにするのが望ましいと考え直しました。
結局、「cocos2d for iPhone レッスンノート」という本のサンプル「Asteroid」をベースにする方法へ戻ることにしました。
この方法は1度挫折していますが、前回のように「1度Asteroidをkobold2dで動かしてみる」なんて悠長なことをやらずに、参考にするだけにして最初から自分のゲームを作ることにします。
ということで、次回は新しいワークスペースファイルをKobold2のスターターアプリで作成するところからやり直しです。