【问题标题】:Libgdx: how to draw a rounded border around a TiledMap with dynamic dimensions?Libgdx:如何在具有动态尺寸的 TiledMap 周围绘制圆形边框?
【发布时间】:2014-03-20 12:02:49
【问题描述】:

在 libgdx 中,我有一个 TiledMap,我用不同的单元格填充:

cell.setTile(new StaticTiledMapTile(reg1));
cell.setTile(new StaticTiledMapTile(reg2));
cell.setTile(new StaticTiledMapTile(reg...));

其中 reg 是纹理区域。

我渲染:

render = new OrthogonalTiledMapRenderer(map);
render.setView(cam);
render.render();

在整个游戏过程中,列数、行数和单元格的大小会有所不同,因此它们必须保持动态。

现在,在这个 TiledMap 周围,我想添加一个圆角边框。下面我将展示一些我打算如何做的 png 示例:从左到右,首先是上边框,然后是右上角,然后是右边框。这些 png 文件中的每一个都具有方形尺寸。

下面是我想要实现的,这里是TiledMap右上角的放大图:

我打算将这些 png 用作 TextureRegions,我可以将其设置为 TiledMap 中的单元格,类似这样:

    for (int x = 0; x < numcol+2; x++) {
            for (int y = 0; y < numrow+2; y++) {
                Cell cell = new Cell();                 

                if (y==numrow+1) {
                    cell.setTile(new StaticTiledMapTile(b_mid_top));
                }

                if (y==0) {
                    cell.setTile(new StaticTiledMapTile(b_mid_bottom));
                }
etc.

我在 png 的尺寸方面遇到了多个问题:正如我所提到的,单元格的大小在整个游戏中可能会有所不同。据我所知,没有办法像我需要的那样从 png 中调整单元格或纹理区域的大小。 所以我可以使用 Image,动态调整它们的大小,将它们作为演员添加到舞台并绘制舞台,但我担心我可能会失去使用 TiledMap 的好处。另外,我一方面必须处理舞台坐标,另一方面还要处理 TiledMap 坐标,这听起来不是最好的方法。

所以我有点失落! 在 TiledMap 周围绘制边框的最佳方法是什么? 我准备放弃我目前的任何想法,以寻求更好的想法。我对 Libgdx 不是很有经验,如果我犯了一些愚蠢的错误,请见谅。

【问题讨论】:

    标签: graphics libgdx border


    【解决方案1】:

    我觉得这个主意不错。如果tilesize改变了bordersize也会改变。您不能在其周围创建不同大小的图块作为框架。如果您想始终创建相同的框架,您可以使用简单的Ninepatch 和地图大小。

    创建这样的东西:

    NinePatch p = new NinePatch(texture, 5, 5, 5, 5); // the edge sizes are 5px here.
    

    在 render 方法中,您以 tilemap 的大小绘制它。您可以从 Map 对象中选择尺寸:

    p.draw(batch, 0, 0, tilesize*tilecountx, tilesize*tilecounty);
    

    如果你不喜欢他的想法,你可以选择第二个版本。创建一个新的TiledMap,将边界作为图块,您需要复制整个图块地图,偏移量为 1 个图块(因为您需要有 1 个图块空间)并创建一个包含 2 行和多列的新图块图。

    应该看起来像这样:

    map = new TiledMap(); // the map with the bordercells
    MapLayers layers = map.getLayers();
    for (int l = 0; l < map1.getLayers().getCount(); l++) {
        // create a new layer which is bigger
        TiledMapTileLayer newlayer = new TiledMapTileLayer(
                ((TiledMapTileLayer) map1.getLayers().get(0)).getWidth() + 2,
                ((TiledMapTileLayer) map1.getLayers().get(0)).getHeight() + 2,
                (int) ((TiledMapTileLayer) map1.getLayers().get(0))
                        .getTileWidth(), (int) ((TiledMapTileLayer) map1
                        .getLayers().get(0)).getTileHeight());
    
        // now add the cells here
        for (int x = 0; x < newlayer.getWidth(); x++) {
            for (int y = 0; y < newlayer.getHeight(); y++) {
                //add the right tile regions here!
                if(x == 0 && y == 0){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(first edge));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
    
                if(x == newlayer.getWidth()-1 && y == 0){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(second edge));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
                if(x == 0 && y == newlayer.getHeight()-1){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(third edge));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
    
                if(x == newlayer.getWidth()-1 && y == newlayer.getHeight()-1){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(fourth edge));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
    
                if(x == 0){ 
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(textureregion for bottom here));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
    
                if(y == 0){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(textureregion for first col));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
    
                if(x == newlayer.getWidth()-1){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(textureregion for toprow));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
    
                if(y == newlayer.getHeight()-1){
                    Cell cell = new Cell();
                    cell.setTile(new StaticTiledMapTile(textureregion for last col));
                    newlayer.setCell(x, y, cell);
                    continue;
                }
                //last but not least if none of this fit add the tile from the old map
                //dont forget the offsett
                newlayer.setCell(x, y, ((TiledMapTileLayer)map1.getLayers().get(l)).getCell(x-1, y-1)); //map1 is the original map without the borders
            }
        }
        layers.add(newlayer);
    }
    

    如果你真的有不同的瓦片大小,我会为你拥有的每个瓦片大小添加一个 Bordertexture,以防你使用 TiledMap 版本。如果您想调整Texture 的大小,请使用Sprite。 Sprite 提供.setSize(w,h) 并扩展了TextureRegion。要创建静态TiledMapTile,您还可以将Sprite 添加为Texture因此,如果您接受这个想法,请在创建 StaticTiledMapTile 之前使用 Sprite 并将其调整为平铺大小。

    【讨论】:

    • 嗨,本恩,感谢您的回答。我不明白什么是map和map1。一个应该包含常规单元格,另一个包含边界单元格吗?
    • map1 是您的原始地图。该地图是新地图,其中还包含边界单元。抱歉,如果这不清楚。我不能保证这段代码有效,它只是一种扩展伪代码,让您了解如何管理它
    • 好的,我明白了。它适用于主地图右侧或顶部的任何边界(正坐标)。但我无法渲染位于主地图左侧或下方的边界(负坐标)。我怎样才能做到这一点?
    • 你需要翻转你的纹理。否则框架在左侧而不是右侧。在其中一种情况下,您需要将其水平翻转甚至旋转。
    • 对不起,如果这是一个愚蠢的问题,但翻转纹理不会允许它添加负坐标,是吗?似乎我无法渲染任何东西,无论纹理是什么,如果 x
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-07
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多