net.dermetfan.gdx.maps.MapUtils.java Source code

Java tutorial

Introduction

Here is the source code for net.dermetfan.gdx.maps.MapUtils.java

Source

/** Copyright 2014 Robin Stumm (serverkorken@gmail.com, http://dermetfan.net)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License. */

package net.dermetfan.gdx.maps;

import java.util.Iterator;

import com.badlogic.gdx.maps.Map;
import com.badlogic.gdx.maps.MapLayer;
import com.badlogic.gdx.maps.MapLayers;
import com.badlogic.gdx.maps.MapObject;
import com.badlogic.gdx.maps.MapObjects;
import com.badlogic.gdx.maps.MapProperties;
import com.badlogic.gdx.maps.tiled.TiledMap;
import com.badlogic.gdx.maps.tiled.TiledMapTile;
import com.badlogic.gdx.maps.tiled.TiledMapTileLayer;
import com.badlogic.gdx.maps.tiled.TiledMapTileSet;
import com.badlogic.gdx.maps.tiled.TiledMapTileSets;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.StringBuilder;
import com.badlogic.gdx.utils.reflect.ClassReflection;

/** provides useful methods for dealing with maps
 *  @author dermetfan */
public class MapUtils {

    /** for internal, temporary usage */
    private static final Vector2 vec2 = new Vector2();

    /** Finds a property in an array of {@link MapProperties}. If multiple {@link MapProperties} contain the value, the later given one's value is returned.
     *  @param key the key
     *  @param defaultValue the default value
     *  @param properties the {@link MapProperties} to search
     *  @param <T> the type of the value
     *  @return the last found value or defaultValue */
    public static <T> T findProperty(String key, T defaultValue, MapProperties... properties) {
        T value = defaultValue;
        for (MapProperties property : properties)
            value = getProperty(property, key, value);
        return value;
    }

    /** Makes sure the return value is of the desired type (null-safe). If the value of the property is not of the desired type, it will be parsed.
     *  @param properties the {@link MapProperties} to get the value from
     *  @param key the key of the property
     *  @param defaultValue the value to return in case the value was null or an empty String or couldn't be returned
     *  @return the key's value as the type of defaultValue */
    @SuppressWarnings("unchecked")
    public static <T> T getProperty(MapProperties properties, String key, T defaultValue) {
        if (properties == null || key == null)
            return defaultValue;

        Object value = properties.get(key);

        if (value == null || value instanceof String && ((String) value).length() == 0)
            return defaultValue;

        if (defaultValue != null) {
            if (defaultValue.getClass() == Boolean.class && !(value instanceof Boolean))
                return (T) Boolean.valueOf(value.toString());

            if (defaultValue.getClass() == Integer.class && !(value instanceof Integer))
                return (T) Integer.valueOf(Float.valueOf(value.toString()).intValue());

            if (defaultValue.getClass() == Float.class && !(value instanceof Float))
                return (T) Float.valueOf(value.toString());

            if (defaultValue.getClass() == Double.class && !(value instanceof Double))
                return (T) Double.valueOf(value.toString());

            if (defaultValue.getClass() == Long.class && !(value instanceof Long))
                return (T) Long.valueOf(value.toString());

            if (defaultValue.getClass() == Short.class && !(value instanceof Short))
                return (T) Short.valueOf(value.toString());

            if (defaultValue.getClass() == Byte.class && !(value instanceof Byte))
                return (T) Byte.valueOf(value.toString());
        }

        return (T) value;
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(Map map) {
        return readableHierarchy(map, 0);
    }

    /** @param map the map to represent
     *  @param indent the indentation size (indent is {@code '\t'})
     *  @return a human-readable hierarchy of the given map and its descendants */
    public static String readableHierarchy(Map map, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (int i = 0; i < indent; i++)
            hierarchy.append('\t');
        hierarchy.append(ClassReflection.getSimpleName(map.getClass())).append('\n');
        hierarchy.append(readableHierarchy(map.getProperties(), indent + 1));
        if (map instanceof TiledMap)
            hierarchy.append(readableHierarchy(((TiledMap) map).getTileSets(), indent + 1));
        hierarchy.append(readableHierarchy(map.getLayers(), indent + 1));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(TiledMapTileSets sets, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (TiledMapTileSet set : sets)
            hierarchy.append(readableHierarchy(set, indent));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(TiledMapTileSet set, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (int i = 0; i < indent; i++)
            hierarchy.append('\t');
        hierarchy.append(ClassReflection.getSimpleName(set.getClass())).append(' ').append(set.getName())
                .append(" (").append(set.size()).append(" tiles)\n");
        hierarchy.append(readableHierarchy(set.getProperties(), indent + 1));
        for (TiledMapTile tile : set)
            hierarchy.append(readableHierarchy(tile, indent + 1));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(TiledMapTile tile, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (int i = 0; i < indent; i++)
            hierarchy.append('\t');
        hierarchy.append(ClassReflection.getSimpleName(tile.getClass())).append(" (ID: ").append(tile.getId())
                .append(", offset: ").append(tile.getOffsetX()).append('x').append(tile.getOffsetY())
                .append(", BlendMode: ").append(tile.getBlendMode()).append(")\n");
        hierarchy.append(readableHierarchy(tile.getProperties(), indent + 1));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(MapLayers layers, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (MapLayer layer : layers)
            hierarchy.append(readableHierarchy(layer, indent));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(MapLayer layer, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (int i = 0; i < indent; i++)
            hierarchy.append('\t');
        hierarchy.append(ClassReflection.getSimpleName(layer.getClass()));
        if (layer instanceof TiledMapTileLayer) {
            TiledMapTileLayer tileLayer = (TiledMapTileLayer) layer;
            hierarchy.append(" (size: ").append(tileLayer.getWidth()).append('x').append(tileLayer.getHeight())
                    .append(", tile size: ").append(tileLayer.getTileWidth()).append('x')
                    .append(tileLayer.getTileHeight()).append(')');
        } else
            hierarchy.append(' ').append(layer.getName());
        hierarchy.append('\n');
        hierarchy.append(readableHierarchy(layer.getProperties(), indent + 1));
        hierarchy.append(readableHierarchy(layer.getObjects(), indent + 1));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(MapObjects objects, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (MapObject object : objects)
            hierarchy.append(readableHierarchy(object, indent));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(MapObject object, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        for (int i = 0; i < indent; i++)
            hierarchy.append('\t');
        hierarchy.append(ClassReflection.getSimpleName(object.getClass())).append(' ').append(object.getName())
                .append('\n');
        hierarchy.append(readableHierarchy(object.getProperties(), indent + 1));
        return hierarchy.toString();
    }

    /** @see #readableHierarchy(com.badlogic.gdx.maps.Map, int) */
    public static String readableHierarchy(MapProperties properties, int indent) {
        StringBuilder hierarchy = new StringBuilder();
        Iterator<String> keys = properties.getKeys();
        while (keys.hasNext()) {
            String key = keys.next();
            for (int i = 0; i < indent; i++)
                hierarchy.append('\t');
            hierarchy.append(key).append(": ").append(properties.get(key).toString()).append('\n');
        }
        return hierarchy.toString();
    }

    /** creates an array of TiledMapTiles from a {@link TiledMapTileSet}
     * @param tiles the {@link TiledMapTileSet} to create an array from
     * @return the array of TiledMapTiles */
    public static TiledMapTile[] toTiledMapTileArray(TiledMapTileSet tiles) {
        TiledMapTile[] tileArray = new TiledMapTile[tiles.size()];
        Iterator<TiledMapTile> tileIterator = tiles.iterator();
        for (int i = 0; tileIterator.hasNext(); i++)
            tileArray[i] = tileIterator.next();
        return tileArray;
    }

    /** converts point to its coordinates on an isometric grid
     *  @param point the point to convert
     *  @param cellWidth the width of the grid cells
     *  @param cellHeight the height of the grid cells
     *  @return the given point converted to its coordinates on an isometric grid */
    public static Vector2 toIsometricGridPoint(Vector2 point, float cellWidth, float cellHeight) {
        point.x /= cellWidth;
        point.y = (point.y - cellHeight / 2) / cellHeight + point.x;
        point.x -= point.y - point.x;
        return point;
    }

    /** @see #toIsometricGridPoint(Vector2, float, float) */
    public static Vector2 toIsometricGridPoint(float x, float y, float cellWidth, float cellHeight) {
        return toIsometricGridPoint(vec2.set(x, y), cellWidth, cellHeight);
    }

    /** @see #toIsometricGridPoint(Vector2, float, float) */
    public static Vector3 toIsometricGridPoint(Vector3 point, float cellWidth, float cellHeight) {
        Vector2 vec2 = toIsometricGridPoint(point.x, point.y, cellWidth, cellHeight);
        point.x = vec2.x;
        point.y = vec2.y;
        return point;
    }

    /** sets the given Vector2 to the max width and height of all {@link TiledMapTileLayer tile layers} of the given map
     *  @param map the map to measure
     *  @return the given Vector2 representing the map size */
    public static Vector2 size(TiledMap map) {
        Array<TiledMapTileLayer> layers = map.getLayers().getByType(TiledMapTileLayer.class);
        float maxWidth = 0, maxTileWidth = 0, maxHeight = 0, maxTileHeight = 0;
        for (TiledMapTileLayer layer : layers) {
            int layerWidth = layer.getWidth(), layerHeight = layer.getHeight();
            float layerTileWidth = layer.getTileWidth(), layerTileHeight = layer.getTileHeight();
            if (layerWidth > maxWidth)
                maxWidth = layerWidth;
            if (layerTileWidth > maxTileWidth)
                maxTileWidth = layerTileWidth;
            if (layerHeight > maxHeight)
                maxHeight = layerHeight;
            if (layerTileHeight > maxTileHeight)
                maxTileHeight = layerTileHeight;
        }
        return vec2.set(maxWidth * maxTileWidth, maxHeight * maxTileHeight);
    }

}