2014-08-31 106 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。如果你有很多额外的字符,如果它们在可见的边界内,则可以通过第一次测试获得另一个加速。