2012-03-11 16 views
1

だから、私は窓の私のタイルマップの描画を処理するための「地図」クラスを作成しようとしてきたが、私は問題は画面にすべてのタイルを描画するために抱えています。SFMLとタイルマップを描画

これは私の問題です:10 * 10 * 5 = 500のタイルを合計する5つのレイヤーを持つ10 * 10タイルのマップがあります(もちろんリアルタイムではタイルが10倍多くなるでしょうそれは悪化するだろう...)それは3次元配列[層] [行] [列]または文字列に格納されている各文字は、私のスプライトシートのタイルのインデックスを表す 私は 'SpriteSheet'スプライトシートを作成し、各スプライトをインデックスから取得します:spriteSheet-> GetSubSprite(idx)。 はので、私は、各スプライトのために呼ばれるべきドローのようなもの(spriteSheet-> GetSubSprite((int型)mapArray [I] [J] [k]を))は、最後に、すべてのゲームLOOPはので、私のゲームは60上で動作すると言うことができますfpsと私は描画する500のタイルを持っています:ゲームは毎秒500 * 60 = 30,000(!)のタイルを描くことを目指しています...

ここに問題のabitを持っている私を見ることができるように...?誰もがスピードの面で十分にこれをimporveする方法を知っていますか? (もちろん、私の現在の構造に対するどんな改良も非常に恵まれています)。

だから、私のSpriteSheet.cppと私のMap.cppファイルがある場合だけで、私は多くの設計ミスを持って知っているが、私の質問に焦点を当ててください、デザインがはるかに仕上げからです。


#include "Map.h" 

sz::Map::Map(std::string path, std::string name, std::string image) : Tmx::Map() { 
    ParseFile(path); 

    if (HasError()) { 
     printf("error code: %d\n", GetErrorCode()); 
     printf("error text: %s\n", GetErrorText().c_str()); 

     system("PAUSE"); 
    } 
    else { 
     mapArray = new unsigned char**[GetNumLayers()]; 
     for(int i = 0; i < GetNumLayers(); i++) { 
      mapArray[i] = new unsigned char*[GetLayer(i)->GetHeight()]; 
      for(int j=0; j<GetLayer(i)->GetHeight(); j++) { 
       mapArray[i][j] = new unsigned char[GetLayer(i)->GetWidth()]; 
       // [layer][row][col] 
      } 
     } 
     //load the array 
     for (int i = 0; i < GetNumLayers(); ++i) { 

      // Get a layer. 
      const Tmx::Layer *layer = GetLayer(i); 

      for (int y = 0; y < layer->GetHeight(); ++y) { 
       for (int x = 0; x < layer->GetWidth(); ++x) { 
        // Get a tile global id. 
        mapArray[i][x][y] = (char)layer->GetTileGid(x, y); 
        //printf("%3d", mapArray[i][x][y]); 
        /* need to fix later on 
        /**************************** 
        // Find a tileset for that id. 
        const Tmx::Tileset *tileset = FindTileset(layer->GetTileGid(x, y)); 
        if (layer->IsTileFlippedHorizontally(x, y)){ 
         printf("h"); 
        }else{ 
         printf(" "); 
        } 
        if (layer->IsTileFlippedVertically(x, y)){ 
         printf("v"); 
        }else{ 
         printf(" "); 
        } 
        if (layer->IsTileFlippedDiagonally(x, y)){ 
         printf("d "); 
        } else { 
         printf(" "); 
        } 
        ****************************/ 
       } 
       //printf("\n"); 
      } 
      //printf("\n\n"); 
     } 
    } 
    tiles = new sz::SpriteSheet(name, image, 33, 33); 
} 

void sz::Map::Draw(sf::RenderWindow *rw) { 
    // dont know what to do T_T 
} 

#include "SpriteSheet.h" 

sz::SpriteSheet::SpriteSheet(std::string name, std::string path, int tileW, int tileH) : sz::GameObject(name, path) { 
    this->tileH = tileH; 
    this->tileW = tileW; 
    numOfTiles = ((this->GetImage()->GetHeight())/tileH) * ((this->GetImage()->GetWidth())/tileW); 
} 

int sz::SpriteSheet::GetTileWidth() { return tileW; } 
int sz::SpriteSheet::GetTileHeight() { return tileH; } 
int sz::SpriteSheet::GetNumOfTiles() { return numOfTiles; } 

sf::Sprite sz::SpriteSheet::GetSubSprite(int idx) { 
    if(idx < 1 || idx > numOfTiles) { 
     std::cout << "Incorrect index!" << std::endl; 
     // need return value 
    } 

    int row=0, col=0, tilesEachRow = (GetImage()->GetWidth()/tileW); 

    while(idx > tilesEachRow) { 
     idx -= tilesEachRow; 
     col++; 
    } 
    row = idx-1; 

    sz::GameObject *sub = new sz::GameObject(name, path); 
    /*std::cout << "tileW: " << tileW << std::endl; 
    std::cout << "tileH: " << tileH << std::endl; 
    std::cout << "row: " << row << std::endl; 
    std::cout << "col: " << col << std::endl; 
    std::cout << "tiles per row: " << tilesEachRow << std::endl; 
    std::cout << "(" << row*tileW << ", " << col*tileH << ", " << (row+1)*tileW << ", " << (col+1)*tileH << ")" << std::endl;*/ 
    sub->SetSubRect(sf::IntRect(row*tileW, col*tileH, (row+1)*tileW, (col+1)*tileH)); 
    return *sub; 
} 

答えて

3

あなたが実際に任意の速度の問題が発生していますか? 1秒間に30,000タイルが多くのように聞こえるかもしれませんが、より現代的なPCでの計算では、それほど問題にはならないかもしれません。

このように言えば、1つのタイルに出力する際に​​、あるタイルに関連する特定のオーバーヘッドがある場合(たとえば、2タイルは1タイルよりも出力に時間がかかりますタイルを組み合わせたもの)。私はSFMLに関して多くのことを知らせているわけではありませんが、ある種の表面/キャンバスシステムがあると想定しています。あなたができることは、表面に静的タイルを一度描画するメソッドを書くことです。その後、ゲームの各フレームごとにこのサーフェスを出力します。これは、タイル形式でタイル内のフレームごとにタイルを繰り返し出力する必要がないことを意味します。すべての静的タイルを1つにまとめて出力するだけです。

このシステムを動的に使用することもできます。タイルを変更する必要がある場合は、このサーフェスの関連する部分を更新されたタイルデータで上書きします。言い換えれば、静的なものだけを残し、更新が必要な領域のみを残します。

1

私はタイルの価値は5画面のレンダリング現代/主流のハードウェアが遅すぎるすべきではないとのことで、アレックスZに同意します。しかし、確かに知る唯一の方法は、それをテストすることです。

また、あなたはあなたのマップは1000×1000のタイルを持っている場合でも、タイルの残りの部分は画面外にあるので、あなただけのフレームごとのタイルの10x10の価値をレンダリングされることを認識する必要があります。あなたの現在の構造がより最適化したい場合は

、あなたは、アレイ内の別々のスプライトとしてあなたのスプライトシートでスプライトのそれぞれを格納する必要があります。そうすれば、単一のタイルにアクセスする必要があるたびにSetSubRectを呼び出す必要はありません。

関連する問題