Divergent
Divergent

Reputation: 141

libGDX - How to copy tiles in a camera viewport instead of by layer?

I am trying to copy a set of tiles(Using Tiled and libGDX) that are within the camera's viewport. Right now I have a copy and paste code:

package com.divergent.tapdown;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer.Cell;

public abstract class TileMapCopier {

public static TiledMapTile[][] copyRegion(TiledMapTileLayer layer, int x, int y, int width, int height) {
    TiledMapTile[][] region = new TiledMapTile[width][height];

    for (int ix = x; ix < x + width; ix++)
        for (int iy = y; iy < y + height; iy++) {
            Cell cell = layer.getCell(ix, iy);
            if (cell == null)
                continue;
            region[ix - x][iy - y] = cell.getTile();
        }

    return region;
}

public static void pasteRegion(TiledMapTileLayer layer, TiledMapTile[][] region, int x, int y) {
    for (int ix = x; ix < x + region.length; ix++)
        for (int iy = y; iy < y + region[ix].length; iy++) {
            Cell cell = layer.getCell(ix, iy);
            if (cell == null) {
                Gdx.app.debug(TileMapCopier.class.getSimpleName(), "pasteRegion: skipped [" + ix + ";" + iy + "]");
                continue;
            }
            cell.setTile(region[ix - x][iy - y]);
        }
}

}

This takes all the cells on the layer, and pastes it to the screen when I want it to:

    public void show() {
    final TiledMapTileLayer layer = ((TiledMapTileLayer) map.getLayers().get(0));
    camera.position.x = layer.getWidth() * layer.getTileWidth() / 2;
    camera.position.y = layer.getHeight() * layer.getTileHeight() / 2;
    camera.zoom = 3;

    Gdx.input.setInputProcessor(new InputAdapter() {

        TiledMapTile[][] clipboard;

        @Override
        public boolean keyDown(int keycode) {
            if(keycode == Keys.C) // copy
                clipboard = TileMapCopier.copyRegion(layer, 0, 0, layer.getWidth(), layer.getHeight() / 2);
            if(keycode == Keys.P) // paste
                TileMapCopier.pasteRegion(layer, clipboard, 0, layer.getHeight() / 2);
            return true;
        }

    });
}

This is great, but its not what I want. Instead of copying the whole layer I only want to copy what is inside of my camera's viewport at the time of copy. I then want to paste it out to the top of the screen and reset the camera's viewport in a way that makes that paste un noticable. (Im essentially taking the lower part of the screen and putting it at the top to generate new values beneath)

How can I do this?

Thanks!

Upvotes: 0

Views: 178

Answers (1)

Vilda
Vilda

Reputation: 1793

You can go through all the tiles and if they are in bounds of the camera viewport, then add it into some array (or just do something with them). You could check the bounds like this:

for(int i = 0; i < allTiles.size; i++) {
    Tile t = allTiles.get(i);
    MapProperties props = t.getProperties();
    float x = (float) props.get("x");
    float y = (float) props.get("y");
    if(x > camera.position.x && x < camera.position.x + camera.vieportWidth
        y > camera.position.y && y < camera.position.y + camera.vieportHeight)
            //do something with the tile, because it IS inside the camera sight
}

Upvotes: 1

Related Questions