2011-09-18 53 views
1

我正在C++中使用一個簡單的一些平臺遊戲,除了我想將瓷磚分組到邊界框以減少物理函數的傳遞之外,我的目標是PC和嵌入式設備,所以它的速度)。加載簡單的地圖格式: 「[char * header] [char bytesize] [bytesize w] [bytesize h] [char tw] [char th] [char * map]」然後它將數組讀取爲2d貼圖,並在可能的情況下對垂直線進行分組。解析一個瓷磚地圖成高效的水平和垂直邊界框

的問題是......可能有人顯示我如何在垂直和水平軸組這批瓷磚爲有效的邊框?

這裏有一個圖像,以幫助解釋,我知道我的語法和拼寫是可怕的:在先進http://thetooth.name/dev/blocks_bic.png

void Environment::load_map(char* mapPath){ 
     cl("Loading Map: %s ", mapPath); 

     FILE* mapFile = fopen(mapPath, "rb"); 
     FILE* mapInfoFile = fopen(strcat(substr(mapPath, 0, strlen(mapPath)-3), "bmd"), "rb"); 

     if (mapFile == NULL || mapInfoFile == NULL) 
     { 
      cl("[ERROR]\n"); 
      throw KLGLException("Error loading map file!"); 
      return; 
     } 

     size_t wordSize; 
     char tBuffer[8] = {}; 
     int w = 0; 
     int h = 0; 
     int tileWidth = 0; 
     int tileHeight = 0; 

     fread(tBuffer, 1, 7, mapFile); 
     if (strcmp(tBuffer, "STME1.0")) 
     { 
      cl("[BADHEADER]"); 
     } 

     fill_n(tBuffer, 8, NULL); 
     fread(tBuffer, 1, 1, mapFile); 
     if (!strcmp(tBuffer, "B")) 
     { 
      wordSize = sizeof(char); 
     }else{ 
      wordSize = sizeof(int); 
     } 

     fseek(mapFile, 8, SEEK_SET); 
     fread(&w, wordSize, 1, mapFile); 
     fread(&h, wordSize, 1, mapFile); 
     fread(&tileWidth, 1, 1, mapFile); 
     fread(&tileHeight, 1, 1, mapFile); 

#define lvLookup y*w+x 
     fill_n(mapData, (w*h)+1, '\0'); 
     fill_n(mapMask, (w*h)+1, '\0'); 

     // Read files into memory... back to front and inside out... 
     for(int y = 0; y < h; y++){ 
      for(int x = 0; x < w; x++){ 
       fread(&mapData[lvLookup], 1, 1, mapFile); 
       fread(&mapMask[lvLookup], 1, 1, mapInfoFile); 
      } 
     } 

     fclose(mapFile); 
     fclose(mapInfoFile); 

     // Parse map data into are geometry vectors 
     for(int x = 0; x < w; x++){ 
      for(int y = 0; y < h; y++){ 
       if(mapData[lvLookup] > 0){ 
        int xl = x; 
        int yl = y; 
        while(mapData[yl*w+x] != 0/* && mapMask[yl*w+x] == 0*/){ 
         yl++; 
        } 
        platforms->push_back(Platform(x*tileWidth, y*tileHeight, 1*tileWidth, (yl-y)*tileHeight, lvLookup, mapData, mapMask)); 
        y = yl-1; 
       } 
      } 
     } 
     cl("[OK]\n"); 
    } 

謝謝!

+0

什麼白線將各個角落圖中意味着什麼?你能給出一個簡單的例子或兩個你期望的輸出類型嗎? – user786653

+0

白線是從左上角到右下角的方塊,它顯示瞭如果一塊瓷磚丟失(綠色塊)將會發生什麼 – thetooth

+0

因此,在第二種情況下,您希望生成的平臺跨越[((0, 0),(0,3)),((0,4),(0,8)),((1,0),(8,8))]或類似的東西? – user786653

回答

0

這有點難看,但我認爲它應該作爲一個起點。它的工作原理是從左到右掃描,從上到下尋找相似的整列。具有挑戰性的部分是跟蹤連續的完整垂直塊並正確輸出「部分」運行。

void find_bounds() 
{ 
    int startx = 0; 
    char last = mapData[0]; 
    for (int x = 0; x < w; x++) { 
     int starty = 0; 
     for (int y = 0; y < h; y++) { 
      char c = mapData[x+y*w]; 
      if (c != last) { 
       if (starty == 0) { 
        // finish last run of complete vertical blocks 
        if(startx != x) { 
         // it ran more than one column, output those first 
         span(last, startx, 0, x-1, h-1); 
         startx = x; 
        } 
        // and a run from the start of this column 
        span(last, x, 0, x, y); 
       } else { 
        // a run within a column 
        span(last, x, starty, x, y); 
       } 
       last = c; 
       starty = y; 
      } 
     } 
     // had a run withing this column or processing last column, finish it up 
     if (starty || x == w-1) { 
      span(last, x, starty, x, h-1); 
      startx= x + 1; 
     } 
    } 
} 

測試套件(前兩個應該從你的插圖對應於第二和第三種情況):

#include <iostream> 
#include <vector> 
using namespace std; 

const int w = 8, h = 8; 
char mapData[w*h+1] = 
#if 1 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
" xxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
#elif 0 
"xxxxxxxx" 
"xxxxxxxx" 
"xxx xxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
#else 
"xxxxxxxx" 
"xx xxxxx" 
"xxxxxxxx" 
"xx xxxxx" 
"xxxx xxx" 
"xxxxxxxx" 
"xxxxxxxx" 
"xxxxxxxx" 
#endif 
; 

void span(char type, int x0, int y0, int x1, int y1) 
{ 
    if (!(x0 == x1 && y0 == y1)) 
     cout << type << " " << x0 << ", " << y0 << " -> " << x1 << ", " << y1 << "\n"; 
} 

int main() 
{ 
    find_bounds(); 
} 
+0

謝謝,效果很棒!現在它只是一個實施斜坡的事情,我的遊戲將完成^ D ^ – thetooth