0

私は現在、RTS ゲームを作成しており、次のように txt ファイルからユニットをロードしています。

1 1 700 200 10

/unit type/ /player/ /x co-ord/ /y co-ord/ /health/

すべてのユニットを保持するために、入植者(現在持っているユニットのみ)オブジェクト(ポインタではない)のベクトルを使用しています

ユニットをロードして画面に描画しようとすると、ユニットが表示されません。いくつかのテストを行ったところ、txt ファイルからロードした後でもベクター「入植者」が空であることが発生します。

main.cpp のコード:

vector<Settler> settlers;
...
void load_units(string filename)
{
settlers.clear();

ifstream unit_file(filename.c_str());
string line;
vector<vector<int> > ww;

while(unit_file.eof())
{
    while(getline(unit_file, line))
    {
        stringstream ss(line);
        int i;
        vector<int> w;
        while( ss >> i )
        {
            w.push_back(i);
        }
        ww.push_back(w);
    }
}

for(int i = 0; i < ww.size(); i++)
{

    int type = ww[i][0];
    int player = ww[i][1];
    int x = ww[i][2];
    int y = ww[i][3];
    int hp = ww[i][4];

    if(type == 1)//settler
    {
        Settler settler(x, y, hp, player);
        settlers.push_back(settler);
    }
}
unit_file.close();}


...



void init() {
SDL_Init( SDL_INIT_EVERYTHING );

TTF_Init();

Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 4096 );

SDL_WM_SetIcon(IMG_Load("icon.png"), NULL);

screen = SDL_SetVideoMode(1600, 900, 32, SDL_FULLSCREEN);

map = IMG_Load("tlo.png");

bar = IMG_Load("bar.png");

pause_menu = IMG_Load("menu.png");

save_game_menu = IMG_Load("save_game_menu.png");

save_prompt = IMG_Load("saved_prompt.png");

load_game_menu = IMG_Load("load_game_menu.png");

load_prompt = IMG_Load("loaded_prompt.png");

intro_control = true;
menu = true;
running = false;
paused = false;
saving = false;
loading = false;

mapX = 0;
mapY = 0;

Xoffset = 0;
Yoffset = 0;

load_map("mapa1.txt");
load_units("units1.txt");

for(int i = 0; i < 60; i++)
{
    string file_frame;

    stringstream ss;
    ss << i + 1;

    if(i < 9)
    {
        file_frame = ("intro/000");
    }else
    {
        file_frame = ("intro/00");
    }

    file_frame.append(ss.str());
    file_frame.append(".png");

    intro[i] = IMG_Load(file_frame.c_str());

}}

...

int main( int argc, char* args[] ) {

int frame = 0;

Timer fps;

init();

Player p1(0, player_1_colour, "player 1");

int frame_control = 0;

while(intro_control)
{

.....

PS: "while(unit_file.eof()){" ステートメントに問題があるのではないかと思います。しかし、それは単なる推測です

4

1 に答える 1

1

コードにはいくつかの問題があります。

  • while ループは、eof が設定されている限りループします (eof が設定されるまでループする必要があります)。
  • while ループを修正しても、eof はそれを超えて読み取った後にのみ設定されるため、まだ間違っているため、無効なエントリが 1 つあります。
  • 最初に行を取得し、それを再び文字列ストリームに入れてから解析するのはなぜですか? ファイル オブジェクトのストリーミング オペレータを直接使用することもできます。

以下はあなたの問題に対するよりクリーンな解決策になると思います:

まず、入植者の構造:

struct Settler {
  int type;     // Maybe some of those should be unsigned, 
                // but I just left them as you already had them
  int player;
  int x;
  int y;
  int health;
};

次に、クラスの >> 演算子をオーバーロードして、任意の入力ストリームからストリーミングできるようにします。最初のパラメーターとして読み取り元のストリームを取り、2 番目のパラメーターとして結果が送信されるオブジェクトを受け取ります。

std::istream& operator>>(std::istream in&, Settler& settler) {
  // Just read the values in the corresponding fields of Settler
  return in >> settler.type 
     >> settler.player 
     >> settler.x 
     >> settler.y 
     >> settler.health;
}

次に、単純な while ループを使用して入植者のファイル全体を読み取ることができます。

int main() {
  std::ifstream file("test.txt");
  Settler current;
  std::vector<Settler> settlers;
  while(file >> current) { // Read as long as it's possible to 
                           // read a Settler
    settlers.push_back(current);
  };
}

ideoneに実用的な例があります (適切な出力のために << もオーバーロードしますが、実際のプログラムでは << をオーバーロードして、>> が読み込むのと同じ形式を生成することができます) 。

于 2013-06-20T19:02:48.573 に答える