忍者ブログ
なんとなくだらだらと。方向性はまだ決まってない。 当方のプログラムでは、山田巧さん作成のDXライブラリを利用させていただいてます。 本サイト http://homepage2.nifty.com/natupaji/DxLib/index.html DX Library Copyright (C) 2001-2008 Takumi Yamada.
[37] [36] [35] [34] [33] [32] [31] [1] [30] [29] [28]
×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

ほんとは、きのう「したらば」で遊んでた時点でここまで出来てた。
モンスターデータの整備なんか考えてたら、ちょっと出しにくかっただけ。




ダウンロード  Entry024.zip (2009.08.04)





んー、考えどころ。
モンスターの数の管理どうしようか。

モンスターデータの中に「全モンスター数」のデータを持って、その数だけ

Unit *mList = new Unit[全モンスター数];

で、動的確保するか。
そうするとプログラム全体をアロー演算子「->」で書き変えないといけないし
クラス配列の受け渡しがうまくいくかどうかも不安なところ。


データ改ざんして遊ぶ人に、作ったモンスターの数を数えさせるのも重いし、
いちどデータ最後まで空読みしてカウント取るのも重い。


結局、大きめに配列を用意して、登録したモンスターの数を返すように変更。


main.cpp


using namespace std;

#include "Unit.h"
#include "Player.h"
#include "OrderList.h"
#include "Histgram.h"

const int MonsterMaxNum = 99;

enum Result
{
    NONE = 0,



int InitEnemyList(Unit (&eList)[MonsterMaxNum])
{
    int EnemyNum = 0;

    ifstream ist("monster.dat");
    if(!ist){
        cout << "cannot open monster.dat.\n";
        return 0;
    }

    string name;
    int HP, Atp, Dfp, Agi, Money;
    while((!ist.eof())&&(EnemyNum<MonsterMaxNum)){
        ist >> name;
        if(ist.eof()) break;
        ist >> HP >> Atp >> Dfp >> Agi >> Money;
        if(ist.fail()) return 0;

        eList[EnemyNum].Init(name,HP,Atp,Dfp,Agi,Money);
//      eList[EnemyNum].ShowStatus();
        ++EnemyNum;
    }
    ist.close();

//  cout << "make MonsterList " << EnemyNum << "numbers.\n";

    return EnemyNum;
}
  :




例によって LoadEnemyList() なんて関数を作ったりしたけど、結局のところ
初期化 InitEnemyList() の仕事でいいじゃんってところに落ち着く。
方針さえ決まっていれば、データのロード自体はいちど通った道。

複数だからwhile()で順次読み込むんだけど、エラー処理がいろいろ面倒。

while((!ist.eof())&&(EnemyNum<MonsterMaxNum)){ の部分は、ファイルの
終端か、敵数のカウントが登録できる最大数を超えていたら終了する。

次の
        ist >> name;
        if(ist.eof()) break;

は、名前を読み込んだ時点でファイルの終端に達していたら終了する。
リストの最後に空行が入ってたりすると、前のwhile()条件では止まらない。

で、
        ist >> HP >> Atp >> Dfp >> Agi >> Money;
        if(ist.fail()) return 0;

数字列を各変数に入れる。
代入エラーになると相変わらずあばばになるんで、あばば状態になったら
エラーで強制終了。

2行ほどコメントにしてるのはデータ確認用。


使ってみる。

main.cpp


int main()
{
    Player player;
    Unit   eList[MonsterMaxNum];
    int EnemyNum;

    srand(static_cast<unsigned int>(time(NULL)));
   
    EnemyNum = InitEnemyList(eList);
    if(EnemyNum==0){
        cout << "モンスターデータの読み込みに失敗しました。\n";
        Sleep(3000);
        return 0;
    }

    InitPlayer(player);

    while(1){
        if(TownEvent(player)==ABORT) break;         // 街
        if(Patrol(player,eList,EnemyNum)==ABORT) break;      // 戦闘
    }

    cout << "\n\n終了。" << endl;
    Sleep(1500);

    return 0;
}




新しくEnemyNum変数を作って、登録モンスターの数を管理するようにする。
読み込んだときに登録数ゼロだったら、何らかの不具合が出てるってことだから
エラーメッセージ表示して終了。
今になって思うに、エラーメッセージの表示は読み込み側の仕事だね。

あと、登録数の情報が必要なのは Patrol() 関数。


main.cpp


Result Patrol(Player &player, Unit (&eList)[MonsterMaxNum], int EnemyNum)
{
    Result res;
    Unit enemy;

    cout << player.getName() << "は、街を出て荒野に向かった。\n";

    for(int i=0; i<EnemyNum; ++i)
    {
        Sleep(800);
        enemy = eList[i];
        cout << "\n" << enemy.getName() << "が あらわれた!\n";
        res = Battle(player,enemy);
        if(res==WIN){         // プレイヤー勝利
            cout << "勝ち。\n";
            player.AddMoney(enemy.GetMoney());
        } else break;
    }
    if(res==WIN){
        // 戦闘勝利で終了してるってことは、大勝利の予感
        cout << "\n\n*+*+*  完 全 勝 利 !!  *+*+*\n";
        cout << "勇者 " << player.getName() << " の名を永遠に称えるがよい。\n\n";
        res = ABORT;
    }
    if(res==LOSE){
        cout << player.getName() << " は死亡した。\n\n-GAME OVER-\n";
        DeleteFile("savedata.dat");
        res = ABORT;
    }
    return res;
}




これでひとまず完成! になるのかな。
Patrol() 関数も、少しさわりたいと思ってるんだけど。



あとは、直感で設定した投げやりな難易度の調整。
これはいちど通してプレイしてみないとわからない。

前回のエントリで「あのひと」と遊んでたときは、けっこう豪快に稼げてたんで、
稼ぎ具合はちょっと渋めに設定している。



ダウンロード  Entry024.zip (2009.08.04)


PR


忍者ブログ [PR]
カレンダー
11 2024/12 01
S M T W T F S
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 31
フリーエリア
バーコード
ブログ内検索
P R
アクセス解析
カウンター