くまちゃんのiOS/Androidゲームプログラミング

マイペースでゲームつくってます。

「はしごゲーム」トモダチの移動処理【Xcode5, iOS7】

f:id:tadakazu1972:20140126132435p:plain
前回のエントリーから続きをコーディングしておりまして、写真のようににぎやかなことになっとります。
・リンゴの追加
・トモダチの追加
・複数ステージに対応
でもって、コードもダラダラとすべて掲載するのもなかなか難儀な長さとなってきました。
というわけで、以下は特にトモダチの移動処理のアルゴリズムのみの抜粋となります。

いやー、シューティングゲームと異なり、ブロックなど自由に移動できないものがある場合のゲームでの自立的な移動の処理はひたすらチェック手続きの嵐ですね。もちろん、あくまでこれは1例で、ある1パターンの動きです。この手続きをいろいろ順番かえたり、チェックする箇所を変えることによって、まったく違う動きが実現できます。移動性格の変数を用意して、それに応じて移動処理を分岐処理すれば、はい、パッ○マンのモンスターのできあがりですね。
ちなみにこのアルゴリズムでは、はしごを降りることはありませんし、落下したあとは右へしか移動しません。また、ステージの作りによっては右の壁をすりぬけるバグが残ってしまっておりますことご留意を。ご愛嬌ということで…。

LadderKumakoView.h

// 略
#define N 5
// 略
    float nx1,nx2,nx3,nx4; // friends MAP x
    float ny1,ny2,ny3,ny4; // friends MAP y
    
    struct friends {
        int pngid;
        float x;
        float y;
        float vx;
        float vy;
        int dir;
    };
    
    struct friends fre[N];
// 略

LadderKumakoView.m

-(id)initWithCoder:(NSCoder*)coder {
// 略
// フレンズ初期設定
        for (int fi=0; fi<N; fi++) {
          fre[fi].pngid=6;
          fre[fi].vx=0.0f;
          fre[fi].vy=0.0f;
          fre[fi].dir=4;
        }
        fre[0].x=32.0f*9.0f; fre[0].y=32.0f*13.0f;
        fre[1].x=32.0f*9.0f; fre[1].y=0.0f;
        fre[2].x=0.0f; fre[2].y=32.0f*13.0f;
        for (int fi2=3; fi2<N; fi2++) {
            fre[fi2].x=32.0f*((int)rand()%9);
            fre[fi2].y=32.0f*((int)rand()%13);
        }
// 略
}

- (void)drawRect:(CGRect)rect
{
// 略
  //*****************************************************************************
    // フレンズの処理
    //*****************************************************************************
    // フレンズ描画
    for (int fi=0; fi<N; fi++) {
     [[draw objectAtIndex:fre[fi].pngid] drawAtPoint:(CGPointMake(fre[fi].x,fre[fi].y))];
    // フレンズ移動処理
    //  32.0fで割り切れるところまで移動したか?
    if ((int)fre[fi].x%32==0 && (int)fre[fi].y%32==0) {
        nx1=fre[fi].x/32.0f; ny1=fre[fi].y/32.0f;
        if (MAP[stage][(int)ny1+1][(int)nx1]==0) { // 足下が空間だったら落下
            fre[fi].dir=3;
        } else if (MAP[stage][(int)ny1][(int)nx1]==2) {  // いまいるところにはしごはあるか?
            // 今までの方向が横移動だったら上へ
            if (fre[fi].dir==2 || fre[fi].dir==4 ) {
                fre[fi].dir=1;
            } else if (fre[fi].dir==1) {
                fre[fi].dir=1;
            } else if (fre[fi].dir==3) {
                fre[fi].dir=3;
            }
        } else if (fre[fi].dir==1) { // はしごをのぼりきったら
            int s=rand()%2;
            if (s==0) {
                fre[fi].dir=2;
            } else {
                fre[fi].dir=4;
            }
            /*if (MAP[(int)ny1+1][(int)nx1-1]==0) { //左ななめ下が空間だったら右へ移動する
                fre[fi].dir=2;
            } else {
                fre[fi].dir=4;
            }*/
        } else if (fre[fi].dir==3) {
            fre[fi].dir=2;
        } else if (fre[fi].dir==4) { // 左方向の先の配列を確認
            nx1=(fre[fi].x-32.0f)/32.0f;
            ny1=fre[fi].y/32.0f;
            if (MAP[stage][(int)ny1][(int)nx1]!=1) { // そのまま進行
                fre[fi].dir=4;
            } else { // 壁なので反転する
                fre[fi].dir=2;
            }
        } else if (fre[fi].dir==2) { // 右方向の先の配列を確認
            nx1=(fre[fi].x+32.0f)/32.0f;
            ny1=fre[fi].y/32.0f;
            if (MAP[stage][(int)ny1][(int)nx1]!=1) { // そのまま進行
                fre[fi].dir=2;
            } else { // 壁なので反転する
                fre[fi].dir=4;
            }
        }
    }
    // 移動方向テーブル
    if (fre[fi].dir==1) {fre[fi].vy=-1.0f; fre[fi].vx=0.0f; }
    if (fre[fi].dir==2) {fre[fi].vx= 1.0f; fre[fi].vy=0.0f; }
    if (fre[fi].dir==3) {fre[fi].vy= 1.0f; fre[fi].vx=0.0f; }
    if (fre[fi].dir==4) {fre[fi].vx=-1.0f; fre[fi].vy=0.0f; }
    // 移動
    fre[fi].x=fre[fi].x+fre[fi].vx;
    if (fre[fi].x<0.0f)   {fre[fi].x=  0.0f; fre[fi].dir=2; }
    if (fre[fi].x>288.0f) {fre[fi].x=288.0f; fre[fi].dir=4; }
    fre[fi].y=fre[fi].y+fre[fi].vy;
    if (fre[fi].y<0.0f)    fre[fi].y=  0.0f;
    if (fre[fi].y>416.0f)  fre[fi].y=416.0f;
    }
// 略
}

https://itunes.apple.com/jp/app/kumachanjanpu2/id789138227?mt=8&uo=4&at=10l8JW&ct=hatenablog