第10回:複雑なパターンを持つ敵

 これまでの作成した敵キャラクターは移動・弾の発射ともに単純なものでしたので、次は中ボスとして、もっとパターンのある敵キャラクターを作成してみます。CEnemy3クラス内に出現してからの時間(ここではフレーム単位)を確認するための変数を格納し、その数値が一定値になるごとに、特定のアクションを行うようにします。
CEnemy3::CEnemy3(float sx)
{
    x = sx;
    left = (x < 320.0f);
    shoot = false;
    hardness = 20;
    frame = 0;
}

void CEnemy3::Init()
{
    CEnemyBase::Init();

    sprite.SetTexture((CTexture*)FindItemBox("cboss"));
    sprite.SetSpriteSize(128, 64);
}

void CEnemy3::Exec()
{
    // 移動
    if(y <= 150){
        y += 1.0f;
    }else{
        // 途中から水平移動に切り替え
        if(left == true){
            x += 1.0f;
        }else{
            x -= 1.0f;
        }

        if(x > 704.0f && x < -64.0f){
            RemoveObject(this);
            return;
        }
    }

    // 弾の発射
    if(frame % 120 == 0 && frame > 0){
        //120フレームごとに連射フラグを切り替える
        shoot = !shoot;

        // 連射終了直後であれば
        // 真下に向かって5way弾を発射する
        if(shoot == false){
            float angle[5] = {90.0f, 70.0f, 50.0f, 110.0f, 130.0f};
            for(int i = 0; i < 5; i++){
            AppendObject(
                new CEnemyBullet(x, y + 18, d2r(angle[i]), 2.5f),
                ENEMYBULLET_PRIORITY, true);
            }
        }
    }
    
    // 連射フラグが有効になっているのであれば
    // 20フレームごとに真下に弾を発射
    if(shoot == true){
        if(frame % 20 == 0){
            AppendObject(
                new CEnemyBullet(x - 40, y + 37, d2r(90.0f), 2.0f),
                ENEMYBULLET_PRIORITY, true);
            AppendObject(
                new CEnemyBullet(x + 40, y + 37, d2r(90.0f), 2.0f),
                ENEMYBULLET_PRIORITY, true);
        }
    }

    frame++;

    sprite.Draw(x, y);
}

void CEnemy3::Damaged()
{
    hardness--;
    if(hardness == 0){
        // 10個の爆炎をランダムで拡散させる
        for(int i = 0; i < 10; i++){
            float angle = d2r((float)(36 * i));
            float size = 0.5f + 2.0f * (float)rand() / (float)(RAND_MAX + 1);
            float speed = 1.0f + 5.0f * (float)rand() / (float)(RAND_MAX + 1);
            AppendObject(new CExplosion(x, y, size, angle, speed),
                EXPLOSION_PRIORITY, true);
        }

        RemoveObject(this);
    }
}