渲染瓷砖Java Libgdx

时间:2014-08-31 09:47:20

标签: java arrays libgdx tiles

我正在尝试渲染一个平铺地图,每次游戏运行时都会生成随机图块。

我有一个数组,它应该包含tile的所有值,然后随机更改:

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. 所有渲染的瓷砖都是污垢。
  2. 这真的减慢了一切。

2 个答案:

答案 0 :(得分:2)

  

2。这真的减慢了一切

这是由地图的大尺寸造成的: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. 不要绘制整个地图。计算当前视口(显示在屏幕上的地图部分)并仅绘制该视口 保持坐标对mapxmapy,它在屏幕上保存地图的左上角坐标。移动此坐标对将使地图在屏幕上移动。如果你想要你的&#34;播放器&#34;要始终保持在屏幕的正中心,它可以像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会自动向下舍入。)

    120x120地图块中可见部分的宽度(和类似,高度)可以计算为

    screen_width/120
    

    但这只是可见的整个地图块的数量。你需要画一个边界&#39;同样,只有部分可见的块。

    应该是更准确的计算(警告:未经测试!):

    int vis_width = (screen_width + (mapx % 120) + (120-(screen_width % 120)))/120;
    
  3. 一个好的一般原则是在内循环中尽可能少地计算。每个图块的乘法120可以很容易地被添加替换。对于最里面的循环中的 xy,也没有必要这样做。

  4. 完成上述所有计算后,检查tile_xoffset是否不小于0,tile_xoffset + visible_width小于平铺图的宽度;当然,y部分也是如此。


  5. 将所有这些放在一起,您的地图绘制代码应如下所示:

    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。如果你有很多额外的字符,如果它们在可见边界内,首先测试可以获得另一个加速。

答案 1 :(得分:0)

地图&#39; array,实际上并不是数据呈现的数组,因为之前的数组已损坏并导致数据重复。