2010-03-15 100 views
1

我會首先說我是OpenGL ES的新手(我昨天開始=),但我確實有一些Java和其他語言的經驗。更好的方法來生成瓷磚

我看了很多教程,當然是嘿嘿,我的工作主要是基於這個。作爲一項測試,我開始創建一個「瓷磚生成器」,以創建一個小型的類似塞爾達的遊戲(只需在紋理方塊中移動花花公子將會很難)。

到目前爲止,我已經實現了一個工作瓦發電機,我定義一個char地圖[] []數組存儲至極瓷磚是:

private char[][] map = { 
      {0, 0, 20, 11, 11, 11, 11, 4, 0, 0}, 
      {0, 20, 16, 12, 12, 12, 12, 7, 4, 0}, 
      {20, 16, 17, 13, 13, 13, 13, 9, 7, 4}, 
      {21, 24, 18, 14, 14, 14, 14, 8, 5, 1}, 
      {21, 22, 25, 15, 15, 15, 15, 6, 2, 1}, 
      {21, 22, 23, 0, 0, 0, 0, 3, 2, 1}, 
      {21, 22, 23, 0, 0, 0, 0, 3, 2, 1}, 
      {26, 0, 0, 0, 0, 0, 0, 3, 2, 1}, 
      {0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 
      {0, 0, 0, 0, 0, 0, 0, 0, 0, 1} 
    }; 

它的工作,但我不喜歡它,我敢肯定有一個尤爲明顯的方式做這些事情:

1)載入紋理:

我創建一個包含我想那地圖上使用的地磚的難看陣列:

private int[] textures = { 
      R.drawable.herbe, //0 
      R.drawable.murdroite_haut, //1 
      R.drawable.murdroite_milieu, //2 
      R.drawable.murdroite_bas, //3 
      R.drawable.angledroitehaut_haut, //4 
      R.drawable.angledroitehaut_milieu, //5 
    }; 

(I板缺此上目的,我目前加載27瓦)

所有論文都存儲在繪製文件夾,每一個是16×16塊。

我使用這個數組生成的紋理和他們在一個HashMap保存爲以後使用:

int[] tmp_tex = new int[textures.length]; 
gl.glGenTextures(textures.length, tmp_tex, 0); 
texturesgen = tmp_tex; //Store the generated names in texturesgen 
for(int i=0; i < textures.length; i++) 
{ 
    //Bitmap bmp = BitmapFactory.decodeResource(context.getResources(), textures[i]); 
    InputStream is = context.getResources().openRawResource(textures[i]); 
    Bitmap bitmap = null; 
    try { 
     //BitmapFactory is an Android graphics utility for images 
     bitmap = BitmapFactory.decodeStream(is); 

    } finally { 
     //Always clear and close 
     try { 
      is.close(); 
      is = null; 
     } catch (IOException e) { 
     } 
    } 
    // Get a new texture name 
    // Load it up 
    this.textureMap.put(new Integer(textures[i]),new Integer(i)); 
    int tex = tmp_tex[i]; 
    gl.glBindTexture(GL10.GL_TEXTURE_2D, tex); 
    //Create Nearest Filtered Texture 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR); 

    //Different possible texture parameters, e.g. GL10.GL_CLAMP_TO_EDGE 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT); 
    gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT); 

    //Use the Android GLUtils to specify a two-dimensional texture image from our bitmap 
    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 

    bitmap.recycle(); 
} 

我敢肯定有一個更好的方式來處理......我只是無法想象它。如果有人有一個想法,我是耳朵。

2)繪製的瓷磚

我所做的就是創建一個單一的廣場和一個紋理貼圖:

/** The initial vertex definition */ 
    private float vertices[] = { 
           -1.0f, -1.0f, 0.0f,  //Bottom Left 
           1.0f, -1.0f, 0.0f,  //Bottom Right 
           -1.0f, 1.0f, 0.0f,  //Top Left 
           1.0f, 1.0f, 0.0f  //Top Right 
               }; 

    private float texture[] = {   
      //Mapping coordinates for the vertices 
       0.0f, 1.0f, 
       1.0f, 1.0f, 
       0.0f, 0.0f, 
       1.0f, 0.0f 

           }; 

然後,在我的繪製函數,我環路通過地圖來定義使用的紋理(指向並啓用緩衝區後):

for(int y = 0; y < Y; y++){ 
    for(int x = 0; x < X; x++){ 
     tile = map[y][x]; 
     try 
      { 
       //Get the texture from the HashMap 
       int textureid = ((Integer) this.textureMap.get(new Integer(textures[tile]))).intValue(); 
       gl.glBindTexture(GL10.GL_TEXTURE_2D, this.texturesgen[textureid]); 
      }  
      catch(Exception e) 
      { 
       return; 
      } 

     //Draw the vertices as triangle strip 
     gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertices.length/3);    
     gl.glTranslatef(2.0f, 0.0f, 0.0f); //A square takes 2x so I move +2x before drawing the next tile 
    } 
    gl.glTranslatef(-(float)(2*X), -2.0f, 0.0f); //Go back to the begining of the map X-wise and move 2y down before drawing the next line 
} 

這很好,我真的認爲在1000 * 10 00或更多的地圖,它會落後於地獄(作爲提醒,這是一個典型的塞爾達世界地圖:http://vgmaps.com/Atlas/SuperNES/LegendOfZelda-ALinkToThePast-LightWorld.png)。

我讀過關於頂點緩衝區對象和DisplayList的東西,但是我找不到一個好的教程,並且nodoby似乎沒有問題,至少一個是最好的/有更好的支持(T1和Nexus One都很老舊) 。

我想就是這樣,我已經提出了很多代碼,但我認爲它有幫助。

在此先感謝!

回答

1

幾件事情:

  1. 沒有必要使用一個HashMap,只需用一個向量/列表。
  2. 有一個包含所有瓷磚的大紋理可能會更快/更容易。使用適當的紋理座標來選擇合適的圖塊。在這裏你可能需要小心紋理過濾。這聽起來像是你正在做2D遊戲,在這種情況下,你可能想要使用最近鄰居濾波器來處理拼貼,並將攝像機夾在整數像素位置。
  3. 使用GL_QUADS而不是GL_TRIANGLE_STRIP會更容易嗎?不知道你的代碼 - 你似乎沒有使用'紋理'數組。
  4. 只要您不繪製不在屏幕上的圖塊,地圖大小不應有任何區別。你的代碼應該是這樣的:

int minX = screenLeft/tileSize; 
int minY = screenBottom/tileSize; 
int maxX = screenRight/tileSize; 
int maxY = screenTop/tilesSize; 
for (int x = minX; x <= maxX; ++x) 
{ 
    for (int y = minY; y < maxY; ++y) 
    { 
     ...