net.dermetfan.gdx.maps.MapUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of libgdx-utils Show documentation
Show all versions of libgdx-utils Show documentation
support library for libGDX
/** Copyright 2014 Robin Stumm ([email protected], 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 the type of the value
* @return the last found value or defaultValue */
public static 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 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 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 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 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);
}
}