简体   繁体   中英

libGDX: How to render a tilemap?

I would like to draw a map consisting of a limited set of tiles in different zoom levels, just like google maps for instance. The reason why I consider using tiles is because the map is very large and in the highest magnification the whole map is very large (about 15000 to 20000 pixels).

Now I thought about creating a quadtree to organize the tiles. Each time a frame is drawn, the quadtree logic would evaluate which tiles to render, so that the rendering time is minimal. However, how would I organize the map tile objects itself? When would I best load the tiles? Creating a sprite for each tile seems to be overkill, as the dimensions of the tiles and position remains static. A SpriteCache doesn't seem to help in this case, as I am only drawing a subset of the map each frame. Also, there are quite a few pros and cons in several cases: When I would load all tiles when launching the application, then it would take a long time to load all of them and cache them in the GPU (Not even considered that all the tiles would fit in the memory). When I would load the necessary tiles on runtime, I suppose to experience kind of a lag when tiles are being rendered.

Is there a "best practice" for a case like this?

I know there is not a right or a wrong answer to this, but I would like to hear other suggestions to solving this problem.

Thanks!!!!

'how would I organize the map tile objects itself?':
a) You could group tiles into Areas;
b) Then your viewer/camera draws only Areas in view (like frustrum culling, but not for each tile, because it's too expensive to ask each tile if it is on view);
c) Each drawn Area draws its Tiles on correct position (relatively to Area.position).

Here question about 'When would I best load the tiles?' could be solved with answer:
- the best approach is to load sprites before draw call AND only for Area.Tiles on view;
- load sprites from pool.

I tested such approach on Map 1000 x 1000 tiles,
where my Viewer (active tiles) was 3 x 3 Area (90 x 90 tiles). And with such approach it doesn't matter for performance how big is map (while you computer have memory:) ), only viewer size matters...


If viewer could have bigger dimension - then you could pre-render whole Area.Tiles to texture and draw directly one Area.texture for each visible Area on each frame.

Textures should be loaded initially when app starts.
Textures could be linked to tiles when Viewer created and when it moves one area up/down/left/right.

for (Area area : Viewer.areas) {
    for (Tile tile : area.tiles) {
        tile.texture = <loaded_texture> OR tile.image = new Libgdx.Image(<loaded_texture>) OR any other appropriate for your tile object way
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM