2014-08-31 102 views
0

我想渲染一個平鋪的貼圖,每次遊戲運行時都會生成隨機貼圖。渲染瓷磚Java Libgdx

我有一個應該保存所有的瓷磚值,然後再以隨機改變的數組:

int[][] map = { 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
        { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,}, 
      }; 
     for (int x = 0; x < map.length; x++) { 
      for (int y = 0; y < map[x].length; y++) { 
       if(map[x][y] == 0){ 
        switch(MathUtils.random(2)){      
        case 0: 
         map[x][y] = 0; 
         break; 
        case 1: 
         map[x][y] = 1; 
         break; 
        case 2: 
         map[x][y] = 2; 
         break; 
         } 
       } 
      } 
     } 

然後我按照使其什麼磚是:

public void render(float delta) { 
     Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
     Gdx.gl.glClearColor(0f, 0f, 0f, 1f); 
     game.batch.begin(); 
     for (int x = 0; x < map.length; x++) { 
      for (int y = 0; y < map[y].length; y++) { 
       if(map[x][y] == 1){ 
        game.batch.draw(stone, x*120, y*120); 
       } 
       if(map[x][y] == 2){ 
        game.batch.draw(grass, x*120, y*120); 
       } 
       if(map[x][y] == 0){ 
        game.batch.draw(dirt, x*120, y*120); 
       } 
      } 
     } 

問題:

  1. 所呈現的所有瓷磚爲二RT。
  2. 它確實減慢了一切。
+1

不應該這是'映射[X]。長度;''中爲(INT Y = 0; Y <映射[Y]。長度; Y ++)''中的方法render'? – 2014-08-31 09:58:42

+0

@ S1LENTWARRIOR是的,這是有道理的,但我只是改變了它,它反應了錯誤:線程「LWJGL應用程序」中的異常java.lang.ArrayIndexOutOfBoundsException:9 – user3165683 2014-08-31 10:02:37

+0

在您的初始'地圖中放入一些'1'和'2' '。這將確定您的隨機展示位置或繪圖代碼中是否存在錯誤。 (一目瞭然,它應該*。*我的工作。另外,請檢查您的圖像加載代碼。也許你不加載正確的圖像。) – usr2564301 2014-08-31 10:29:23

回答

0

'map'數組實際上並不是數據從那裏被渲染的數組,因爲之前的數組被損壞並導致數據重複。

2

2. It really slows everything down

這是由於您的地圖的大尺寸:1920 x 1080塊引起的。對於每個120 x 120像素的圖塊,這個像素高達230,400 x 129,600像素。渲染所有這些對於OpenGL來說都不是問題,因爲它會自動剪切一切看不見的東西,並且OpenGL在確定可見性方面非常高效。但是之前您將它發送給批處理渲染器,您已經完成了很多可以輕鬆避免的工作。

(下面的代碼片段可能不正確的Java。)

  1. 不要使用if - 甚至更好switch - 的內部繪圖循環中。創建一個索引查找數組:

    Texture textures[] = { dirt, stone, grass }; 
    

    ,然後裏面的循環使用:

    game.batch.draw(textures[map[x][y]], x*120, y*120); 
    
  2. 不要畫整個地圖。計算當前視口(顯示在屏幕上的地圖部分)並僅繪製該視口。
    保持一個座標對mapx,mapy在屏幕上保存地圖的左上角座標。移動這個座標對將使地圖在屏幕上移動。如果你想讓你的「玩家」永遠停留在屏幕的中心位置,它可以簡單到mapx = (player_x - screen_width/2)。請注意檢查超出範圍的值。

    地圖上,這將是可見的開始在

    int tile_xoffset = floor (mapx/120); 
    int tile_yoffset = floor (mapy/120); 
    

    捨去,因爲如果mapx119你仍然會看到map[0][y]一個像素帶的一部分。 (小提示:floor實際上是不必要的。當將float轉換爲整數時,Java自動舍入。)

    在120×120映射塊的可見部分的寬度(以及類似的,高度)可被計算爲

    screen_width/120 
    

    但這只是的整個映射塊是可見的數目。您還需要繪製一個「邊框」,以及僅部分可見的塊。

    更精確的計算應該是這樣的(警告:未經):

    int vis_width = (screen_width + (mapx % 120) + (120-(screen_width % 120)))/120; 
    
  3. 一個很好的一般原則是做盡可能少的計算儘可能在內部循環。乘以120爲每個瓷磚可以很容易地被添加替換。這也是沒有必要的xy最裏面的循環內做到這一點。

  4. 做完所有上述計算後,檢查tile_xoffset是否不小於0,並且tile_xoffset + visible_width小於tile地圖的寬度;當然,對於y部分也是如此。


把所有的這一起,你的地圖繪製代碼應該是這個樣子:

xp = (tile_xoffset*120) - mapx; 
for (int x = 0; x < visible_width; x++) 
{ 
    yp = (tile_yoffset*120) - mapy; 
    for (int y = 0; y < visible_height; y++) 
    { 
     game.batch.draw(textures[map[x][y]], xp, yp); 
     yp += 120; 
    } 
    xp += 120; 
} 

要在這個地圖上面畫符,可以抵消其座標通過-mapx,-mapy。如果你有很多額外的字符,如果它們在可見的邊界內,則可以通過第一次測試獲得另一個加速。