mirror of
https://github.com/AndorsTrailRelease/ATCS.git
synced 2025-10-27 18:44:03 +01:00
470 lines
14 KiB
Java
470 lines
14 KiB
Java
/*
|
|
* Copyright 2004-2010, Thorbjørn Lindeijer <thorbjorn@lindeijer.nl>
|
|
* Copyright 2004-2006, Adam Turk <aturk@biggeruniverse.com>
|
|
*
|
|
* This file is part of libtiled-java.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
*
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
* EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
package tiled.core;
|
|
|
|
import java.awt.Rectangle;
|
|
import java.util.*;
|
|
|
|
/**
|
|
* The Map class is the focal point of the <code>tiled.core</code> package.
|
|
*/
|
|
public class Map implements Iterable<MapLayer>
|
|
{
|
|
public static final int ORIENTATION_ORTHOGONAL = 1;
|
|
public static final int ORIENTATION_ISOMETRIC = 2;
|
|
public static final int ORIENTATION_HEXAGONAL = 4;
|
|
/** Shifted (used for iso and hex). */
|
|
public static final int ORIENTATION_SHIFTED = 5;
|
|
|
|
private Vector<MapLayer> layers;
|
|
private Vector<ObjectGroup> objectGroups;
|
|
private Vector<TileLayer> tileLayers;
|
|
private Vector<TileSet> tileSets;
|
|
|
|
private int tileWidth, tileHeight;
|
|
private int orientation = ORIENTATION_ORTHOGONAL;
|
|
private Properties properties;
|
|
private String filename;
|
|
protected Rectangle bounds; // in tiles
|
|
|
|
/**
|
|
* @param width the map width in tiles.
|
|
* @param height the map height in tiles.
|
|
*/
|
|
public Map(int width, int height) {
|
|
layers = new Vector<MapLayer>();
|
|
bounds = new Rectangle(width, height);
|
|
properties = new Properties();
|
|
tileSets = new Vector<TileSet>();
|
|
objectGroups = new Vector<ObjectGroup>();
|
|
tileLayers = new Vector<TileLayer>();
|
|
}
|
|
|
|
/**
|
|
* Returns the total number of layers.
|
|
*
|
|
* @return the size of the layer vector
|
|
*/
|
|
public int getLayerCount() {
|
|
return layers.size();
|
|
}
|
|
|
|
/**
|
|
* Changes the bounds of this plane to include all layers completely.
|
|
*/
|
|
public void fitBoundsToLayers() {
|
|
int width = 0;
|
|
int height = 0;
|
|
|
|
Rectangle layerBounds = new Rectangle();
|
|
|
|
for (int i = 0; i < layers.size(); i++) {
|
|
getLayer(i).getBounds(layerBounds);
|
|
if (width < layerBounds.width) width = layerBounds.width;
|
|
if (height < layerBounds.height) height = layerBounds.height;
|
|
}
|
|
|
|
setBounds(width, height);
|
|
}
|
|
|
|
/**
|
|
* Returns a <code>Rectangle</code> representing the maximum bounds in
|
|
* tiles.
|
|
* @return a new rectangle containing the maximum bounds of this plane
|
|
*/
|
|
public Rectangle getBounds() {
|
|
return new Rectangle(bounds);
|
|
}
|
|
|
|
public void setBounds(int width, int height) {
|
|
bounds.width = width;
|
|
bounds.height = height;
|
|
}
|
|
|
|
public MapLayer addLayer(MapLayer layer) {
|
|
layer.setMap(this);
|
|
layers.add(layer);
|
|
if (layer instanceof TileLayer) {
|
|
tileLayers.add((TileLayer) layer);
|
|
} else if (layer instanceof ObjectGroup) {
|
|
objectGroups.add((ObjectGroup) layer);
|
|
}
|
|
return layer;
|
|
}
|
|
|
|
public void setLayer(int index, MapLayer layer) {
|
|
layer.setMap(this);
|
|
layers.set(index, layer);
|
|
if (layer instanceof TileLayer) {
|
|
tileLayers.set(index - objectGroups.size(), (TileLayer) layer);
|
|
} else if (layer instanceof ObjectGroup) {
|
|
objectGroups.set(index, (ObjectGroup) layer);
|
|
}
|
|
}
|
|
|
|
public void insertLayer(int index, MapLayer layer) {
|
|
layer.setMap(this);
|
|
layers.add(index, layer);
|
|
if (layer instanceof TileLayer) {
|
|
tileLayers.add(index - objectGroups.size(), (TileLayer) layer);
|
|
} else if (layer instanceof ObjectGroup) {
|
|
objectGroups.add(index, (ObjectGroup) layer);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the layer at the specified index. Layers above this layer will
|
|
* move down to fill the gap.
|
|
*
|
|
* @param index the index of the layer to be removed
|
|
* @return the layer that was removed from the list
|
|
*/
|
|
public MapLayer removeLayer(int index) {
|
|
if (index < objectGroups.size()) {
|
|
objectGroups.remove(index);
|
|
} else if (index - objectGroups.size() < tileLayers.size()){
|
|
tileLayers.remove(index - objectGroups.size());
|
|
}
|
|
return layers.remove(index);
|
|
}
|
|
|
|
/**
|
|
* Removes all layers from the plane.
|
|
*/
|
|
public void removeAllLayers() {
|
|
layers.removeAllElements();
|
|
objectGroups.removeAllElements();
|
|
tileLayers.removeAllElements();
|
|
}
|
|
|
|
/**
|
|
* Returns the layer vector.
|
|
*
|
|
* @return Vector the layer vector
|
|
*/
|
|
public Vector<MapLayer> getLayers() {
|
|
return layers;
|
|
}
|
|
|
|
/**
|
|
* Returns the tile layer vector.
|
|
*
|
|
* @return Vector the tile layer vector
|
|
*/
|
|
public Vector<TileLayer> getTileLayers() {
|
|
return tileLayers;
|
|
}
|
|
|
|
/**
|
|
* Returns the object group vector.
|
|
*
|
|
* @return Vector the object group vector
|
|
*/
|
|
public Vector<ObjectGroup> getObjectGroup() {
|
|
return objectGroups;
|
|
}
|
|
|
|
/**
|
|
* Sets the layer vector to the given java.util.Vector.
|
|
*
|
|
* @param layers the new set of layers
|
|
*/
|
|
public void setLayers(Vector<MapLayer> layers) {
|
|
this.layers = layers;
|
|
}
|
|
|
|
/**
|
|
* Returns the layer at the specified vector index.
|
|
*
|
|
* @param i the index of the layer to return
|
|
* @return the layer at the specified index, or null if the index is out of
|
|
* bounds
|
|
*/
|
|
public MapLayer getLayer(int i) {
|
|
try {
|
|
return layers.get(i);
|
|
} catch (ArrayIndexOutOfBoundsException e) {
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Resizes this plane. The (dx, dy) pair determines where the original
|
|
* plane should be positioned on the new area. Only layers that exactly
|
|
* match the bounds of the map are resized, any other layers are moved by
|
|
* the given shift.
|
|
*
|
|
* @see tiled.core.MapLayer#resize
|
|
*
|
|
* @param width The new width of the map.
|
|
* @param height The new height of the map.
|
|
* @param dx The shift in x direction in tiles.
|
|
* @param dy The shift in y direction in tiles.
|
|
*/
|
|
public void resize(int width, int height, int dx, int dy) {
|
|
for (MapLayer layer : this) {
|
|
if (layer.bounds.equals(bounds)) {
|
|
layer.resize(width, height, dx, dy);
|
|
} else {
|
|
layer.setOffset(layer.bounds.x + dx, layer.bounds.y + dy);
|
|
}
|
|
}
|
|
|
|
bounds.width = width;
|
|
bounds.height = height;
|
|
}
|
|
|
|
/**
|
|
* Determines whether the point (x,y) falls within the plane.
|
|
*
|
|
* @param x
|
|
* @param y
|
|
* @return <code>true</code> if the point is within the plane,
|
|
* <code>false</code> otherwise
|
|
*/
|
|
public boolean inBounds(int x, int y) {
|
|
return x >= 0 && y >= 0 && x < bounds.width && y < bounds.height;
|
|
}
|
|
|
|
public Iterator<MapLayer> iterator() {
|
|
return layers.iterator();
|
|
}
|
|
|
|
/**
|
|
* Adds a Tileset to this Map. If the set is already attached to this map,
|
|
* <code>addTileset</code> simply returns.
|
|
*
|
|
* @param tileset a tileset to add
|
|
*/
|
|
public void addTileset(TileSet tileset) {
|
|
if (tileset == null || tileSets.indexOf(tileset) > -1) {
|
|
return;
|
|
}
|
|
|
|
Tile t = tileset.getTile(0);
|
|
|
|
if (t != null) {
|
|
int tw = t.getWidth();
|
|
int th = t.getHeight();
|
|
if (tw != tileWidth) {
|
|
if (tileWidth == 0) {
|
|
tileWidth = tw;
|
|
tileHeight = th;
|
|
}
|
|
}
|
|
}
|
|
|
|
tileSets.add(tileset);
|
|
}
|
|
|
|
/**
|
|
* Removes a {@link TileSet} from the map, and removes any tiles in the set
|
|
* from the map layers.
|
|
*
|
|
* @param tileset TileSet to remove
|
|
*/
|
|
public void removeTileset(TileSet tileset) {
|
|
// Sanity check
|
|
final int tilesetIndex = tileSets.indexOf(tileset);
|
|
if (tilesetIndex == -1)
|
|
return;
|
|
|
|
// Go through the map and remove any instances of the tiles in the set
|
|
for (Tile tile : tileset) {
|
|
for (MapLayer ml : this) {
|
|
if (ml instanceof TileLayer) {
|
|
((TileLayer) ml).removeTile(tile);
|
|
}
|
|
}
|
|
}
|
|
|
|
tileSets.remove(tileset);
|
|
}
|
|
|
|
/**
|
|
* @return the map properties
|
|
*/
|
|
public Properties getProperties() {
|
|
return properties;
|
|
}
|
|
|
|
public void setProperties(Properties prop) {
|
|
properties = prop;
|
|
}
|
|
|
|
public void setFilename(String filename) {
|
|
this.filename = filename;
|
|
}
|
|
|
|
/**
|
|
* Sets a new tile width.
|
|
*
|
|
* @param width the new tile width
|
|
*/
|
|
public void setTileWidth(int width) {
|
|
tileWidth = width;
|
|
}
|
|
|
|
/**
|
|
* Sets a new tile height.
|
|
*
|
|
* @param height the new tile height
|
|
*/
|
|
public void setTileHeight(int height) {
|
|
tileHeight = height;
|
|
}
|
|
|
|
public void setOrientation(int orientation) {
|
|
this.orientation = orientation;
|
|
}
|
|
|
|
public String getFilename() {
|
|
return filename;
|
|
}
|
|
|
|
/**
|
|
* Returns a vector with the currently loaded tileSets.
|
|
*
|
|
* @return Vector
|
|
*/
|
|
public Vector<TileSet> getTileSets() {
|
|
return tileSets;
|
|
}
|
|
|
|
/**
|
|
* Returns width of map in tiles.
|
|
*
|
|
* @return int
|
|
*/
|
|
public int getWidth() {
|
|
return bounds.width;
|
|
}
|
|
|
|
/**
|
|
* Returns height of map in tiles.
|
|
*
|
|
* @return int
|
|
*/
|
|
public int getHeight() {
|
|
return bounds.height;
|
|
}
|
|
|
|
/**
|
|
* Returns default tile width for this map.
|
|
*
|
|
* @return the default tile width
|
|
*/
|
|
public int getTileWidth() {
|
|
return tileWidth;
|
|
}
|
|
|
|
/**
|
|
* Returns default tile height for this map.
|
|
*
|
|
* @return the default tile height
|
|
*/
|
|
public int getTileHeight() {
|
|
return tileHeight;
|
|
}
|
|
|
|
/**
|
|
* Returns wether the given tile coordinates fall within the map
|
|
* boundaries.
|
|
*
|
|
* @param x The tile-space x-coordinate
|
|
* @param y The tile-space y-coordinate
|
|
* @return <code>true</code> if the point is within the map boundaries,
|
|
* <code>false</code> otherwise
|
|
*/
|
|
public boolean contains(int x, int y) {
|
|
return x >= 0 && y >= 0 && x < bounds.width && y < bounds.height;
|
|
}
|
|
|
|
/**
|
|
* Returns the maximum tile height. This is the height of the highest tile
|
|
* in all tileSets or the tile height used by this map if it's smaller.
|
|
*
|
|
* @return int The maximum tile height
|
|
*/
|
|
public int getTileHeightMax() {
|
|
int maxHeight = tileHeight;
|
|
|
|
for (TileSet tileset : tileSets) {
|
|
int height = tileset.getTileHeight();
|
|
if (height > maxHeight) {
|
|
maxHeight = height;
|
|
}
|
|
}
|
|
|
|
return maxHeight;
|
|
}
|
|
|
|
/**
|
|
* Swaps the tile sets at the given indices.
|
|
*/
|
|
public void swapTileSets(int index0, int index1) {
|
|
if (index0 == index1) return;
|
|
TileSet set = tileSets.get(index0);
|
|
tileSets.set(index0, tileSets.get(index1));
|
|
tileSets.set(index1, set);
|
|
}
|
|
|
|
/**
|
|
* Returns the orientation of this map. Orientation will be one of
|
|
* {@link Map#ORIENTATION_ISOMETRIC}, {@link Map#ORIENTATION_ORTHOGONAL},
|
|
* {@link Map#ORIENTATION_HEXAGONAL} and {@link Map#ORIENTATION_SHIFTED}.
|
|
*
|
|
* @return The orientation from the enumerated set
|
|
*/
|
|
public int getOrientation() {
|
|
return orientation;
|
|
}
|
|
|
|
/**
|
|
* Returns string describing the map. The form is <code>Map[width x height
|
|
* x layers][tileWidth x tileHeight]</code>, for example <code>
|
|
* Map[64x64x2][24x24]</code>.
|
|
*
|
|
* @return string describing map
|
|
*/
|
|
public String toString() {
|
|
return "Map[" + bounds.width + "x" + bounds.height + "x" +
|
|
getLayerCount() + "][" + tileWidth + "x" +
|
|
tileHeight + "]";
|
|
}
|
|
|
|
public boolean containsLayer(MapLayer layer) {
|
|
return layers.contains(layer);
|
|
}
|
|
|
|
public int getLayerIndex(MapLayer layer) {
|
|
return layers.indexOf(layer);
|
|
}
|
|
}
|