LibGdx:在后台绘制棋盘的最有效方法

时间:2014-03-10 12:13:09

标签: grid libgdx draw scene2d

我正在用libgdx构建游戏。 游戏画面是一个带有Scene2D演员的网格。演员显示在正面。 我想画一个看起来像棋盘的背景,用一种颜色着色每2个细胞,用另一种颜色着色其他细胞。

这很容易做但我想知道libgdx中是否有类可以优化这样的背景,使其尽可能轻巧和优化。例如,单独着色每个单元格应该可以工作,但似乎不是最好的方法。

我已经开始深入研究TiledMapTileLayer类,但是我必须使用Tile对象填充每个单元格,这似乎比一种颜色更重。

理想情况下,我想简单地定义2种颜色,设置单元格的坐标,并用颜色填充它们,而不必逐个使用对象或为单元格着色。

最好的方法是什么?

2 个答案:

答案 0 :(得分:3)

我认为最简单的方法是,你定义2个Tiles black and white或者什么,并在运行时使用这两个tile创建TiledMap。它只是用2个for cells(x,y)用相同的tile填充单元格。应该很容易管理。将其纹理放在一个纹理内,以便最小化渲染时间。你不需要自己处理渲染和类似的东西。您只需要使用TiledMap系统实现板的创建。没有解决方案可以定义2种颜色。你总是需要以某种方式迭代细胞。

看看example code of libgdx for creating a tiledmap on runtime

您几乎可以复制粘贴它,只需更改此行

即可
cell.setTile(new StaticTiledMapTile(splitTiles[ty][tx]));

根据您当前所在的单元格,只需添加背面和白色的纹理区域。像这样的东西

if(y % 2 !=0){
    cell.setTile(new StaticTiledMapTile(blackTextureRegion)); //or what color you need
}else{
    cell.setTile(new StaticTiledMapTile(whiteTextureRegion)); //or what color you need
}

这将创建黑色和白色行。我建议使用Atlas作为TextureRegions或自己定义它们。

使用x和y值并检查您需要的值。也许改变我写给你需要的权利的if语句。

如果你真的只想定义一种颜色,你需要在运行时用32x32填充颜色来创建一个Pixmap,然后用它创建一个纹理。您可以使用它来创建Tilemap,如上所示。

以下是如何创建所需的32x32切片。您甚至可以为两个图块创建一个32x64的纹理。只需创建0,0,32,3232,0,32,32的TextureRegions即可。

Pixmap pixmap = new Pixmap(64, 32, Format.RGBA8888);
pixmap.setColor(Color.BLUE); // add your 1 color here
pixmap.fillRectangle(0, 0, 32, 32);

pixmap.setColor(Color.RED); // add your 2 color here
pixmap.fillRectangle(32, 0, 32, 32);
// the outcome is an texture with an blue left square and an red right square
Texture t = new Texture(pixmap);
TextureRegion reg1 = new TextureRegion(t, 0, 0, 32, 32);
TextureRegion reg2 = new TextureRegion(t, 32, 0, 32, 32);
//now use this to create the StaticTiledMapTile

如果你把它粘在一起,你应该拥有你想拥有的系统。 你走了:

Pixmap pixmap = new Pixmap(64, 32, Format.RGBA8888);
pixmap.setColor(Color.BLUE); // add your 1 color here
pixmap.fillRectangle(0, 0, 32, 32);

pixmap.setColor(Color.RED); // add your 2 color here
pixmap.fillRectangle(32, 0, 32, 32);
// the outcome is an texture with an blue left square and an red right
// square
Texture t = new Texture(pixmap);
TextureRegion reg1 = new TextureRegion(t, 0, 0, 32, 32);
TextureRegion reg2 = new TextureRegion(t, 32, 0, 32, 32);

TiledMap map = new TiledMap();
MapLayers layers = map.getLayers();
for (int l = 0; l < 20; l++) {
    TiledMapTileLayer layer = new TiledMapTileLayer(150, 100, 32, 32);
    for (int x = 0; x < 150; x++) {
        for (int y = 0; y < 100; y++) {
            Cell cell = new Cell();
            if (y % 2 != 0) {
                if (x % 2 != 0) {
                    cell.setTile(new StaticTiledMapTile(reg1));
                } else {
                    cell.setTile(new StaticTiledMapTile(reg2));
                }
            } else {
                if (x % 2 != 0) {
                    cell.setTile(new StaticTiledMapTile(reg2));
                } else {
                    cell.setTile(new StaticTiledMapTile(reg1));
                }
            }
            layer.setCell(x, y, cell);
        }
    }
    layers.add(layer);
}

要渲染此内容,您只需创建OrthogonalTiledMapRenderer并调用render()方法。

在最小的例子中,这是输出:

cheststyle

已经有一些宽度和高度以及layercount的参数。我认为你不需要多个层 代码:

public class MainClass implements ApplicationListener {
    private OrthographicCamera camera;
    private OrthogonalTiledMapRenderer render;
    private final static int width = 150, height = 100, layercount = 1;
    private TiledMap map;

    @Override
    public void create() {
        float w = Gdx.graphics.getWidth();
        float h = Gdx.graphics.getHeight();

        camera = new OrthographicCamera(w, h);

        Pixmap pixmap = new Pixmap(64, 32, Format.RGBA8888);
        pixmap.setColor(Color.BLUE); // add your 1 color here
        pixmap.fillRectangle(0, 0, 32, 32);

        pixmap.setColor(Color.RED); // add your 2 color here
        pixmap.fillRectangle(32, 0, 32, 32);
        // the outcome is an texture with an blue left square and an red right
        // square
        Texture t = new Texture(pixmap);
        TextureRegion reg1 = new TextureRegion(t, 0, 0, 32, 32);
        TextureRegion reg2 = new TextureRegion(t, 32, 0, 32, 32);

        map = new TiledMap();
        MapLayers layers = map.getLayers();
        for (int l = 0; l < layercount; l++) {
            TiledMapTileLayer layer = new TiledMapTileLayer(width, height, 32,
                    32);
            for (int x = 0; x < width; x++) {
                for (int y = 0; y < height; y++) {
                    Cell cell = new Cell();
                    if (y % 2 != 0) {
                        if (x % 2 != 0) {
                            cell.setTile(new StaticTiledMapTile(reg1));
                        } else {
                            cell.setTile(new StaticTiledMapTile(reg2));
                        }
                    } else {
                        if (x % 2 != 0) {
                            cell.setTile(new StaticTiledMapTile(reg2));
                        } else {
                            cell.setTile(new StaticTiledMapTile(reg1));
                        }
                    }
                    layer.setCell(x, y, cell);
                }
            }
            layers.add(layer);
        }
        render = new OrthogonalTiledMapRenderer(map);
        render.setView(camera);
        camera.translate(Gdx.graphics.getWidth() / 2,
                Gdx.graphics.getHeight() / 2);
    }

    @Override
    public void dispose() {
        render.dispose();
        map.dispose();
    }

    private static final float movmentspeed = 5f;

    @Override
    public void render() {

        Gdx.gl.glClearColor(1, 1, 1, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        camera.update();
        render.setView(camera);
        render.render();

        if (Gdx.input.isKeyPressed(Keys.LEFT)) {
            camera.translate(-movmentspeed, 0);
        } else if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
            camera.translate(movmentspeed, 0);
        } else if (Gdx.input.isKeyPressed(Keys.UP)) {
            camera.translate(0, movmentspeed);
        } else if (Gdx.input.isKeyPressed(Keys.DOWN)) {
            camera.translate(0, -movmentspeed);
        }
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

最后。我不能告诉你这是否有效!也许有更有效的方法,但这会在运行时创建你的东西​​,如果你不做一遍又一遍的创建它应该不是一个问题,因为你只是在加载游戏后这样做。我认为它的效率很高,因为渲染效率很高,只需绘制屏幕上可见的图块。此外,您只需使用1个纹理作为背景,因此它只需要一个OpenGl绑定整个背景。

答案 1 :(得分:-1)