[tiled] r737 - in trunk: . src/tiled/core src/tiled/mapeditor/dialogs src/tiled/view
tiled-svn at biggeruniverse.com
tiled-svn at biggeruniverse.com
Fri Apr 11 02:30:37 PDT 2008
Author: aturk
Date: 2008-04-11 04:30:37 -0500 (Fri, 11 Apr 2008)
New Revision: 737
Modified:
trunk/build.xml
trunk/src/tiled/core/AnimatedTile.java
trunk/src/tiled/mapeditor/dialogs/NewMapDialog.java
trunk/src/tiled/view/HexMapView.java
Log:
I have merged Matthias Kievernagel's HexMapView changes in, and re-enabled hex maps in NewMapDialog. It's incomplete, but by putting it in there I hope to stimulate some development.
Modified: trunk/build.xml
===================================================================
--- trunk/build.xml 2008-04-09 22:40:26 UTC (rev 736)
+++ trunk/build.xml 2008-04-11 09:30:37 UTC (rev 737)
@@ -75,8 +75,9 @@
<target name="core" depends="compile"
description="Generate a core I/O distribution for use in games, etc.">
+ <mkdir dir="${dist}"/>
<jar jarfile="${dist}/tiled-core.jar"
- basedir="${build}" includes="tiled/core/**/*.class,tiled/io/**,tiled/mapeditor/util/cutter/**,tiled/util/Util.class,tiled/util/Base64.class,tiled/util/NumberedSet.class,tiled/mapeditor/util/TransparentImageFilter.class"/>
+ basedir="${build}" includes="tiled/core/**/*.class,tiled/io/**,tiled/mapeditor/util/cutter/**,tiled/mapeditor/util/MapChangeListener.class,tiled/mapeditor/util/MapChangedEvent.class,tiled/util/Util.class,tiled/util/Base64.class,tiled/util/NumberedSet.class,tiled/mapeditor/util/TransparentImageFilter.class"/>
</target>
<target name="dist_dep" depends="compile_dep"
Modified: trunk/src/tiled/core/AnimatedTile.java
===================================================================
--- trunk/src/tiled/core/AnimatedTile.java 2008-04-09 22:40:26 UTC (rev 736)
+++ trunk/src/tiled/core/AnimatedTile.java 2008-04-11 09:30:37 UTC (rev 737)
@@ -1,5 +1,5 @@
/*
- * Tiled Map Editor, (c) 2005
+ * Tiled Map Editor, (c) 2004-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
Modified: trunk/src/tiled/mapeditor/dialogs/NewMapDialog.java
===================================================================
--- trunk/src/tiled/mapeditor/dialogs/NewMapDialog.java 2008-04-09 22:40:26 UTC (rev 736)
+++ trunk/src/tiled/mapeditor/dialogs/NewMapDialog.java 2008-04-11 09:30:37 UTC (rev 737)
@@ -135,8 +135,8 @@
mapTypeChooser = new JComboBox();
mapTypeChooser.addItem(ORTHOGONAL_MAPTYPE);
mapTypeChooser.addItem(ISOMETRIC_MAPTYPE);
+ mapTypeChooser.addItem(HEXAGONAL_MAPTYPE);
// TODO: Enable views when implemented decently
- //mapTypeChooser.addItem(HEXAGONAL_MAPTYPE);
//mapTypeChooser.addItem(SHIFTED_MAPTYPE);
JPanel miscPropPanel = new VerticalStaticJPanel();
Modified: trunk/src/tiled/view/HexMapView.java
===================================================================
--- trunk/src/tiled/view/HexMapView.java 2008-04-09 22:40:26 UTC (rev 736)
+++ trunk/src/tiled/view/HexMapView.java 2008-04-11 09:30:37 UTC (rev 737)
@@ -1,5 +1,5 @@
/*
- * Tiled Map Editor, (c) 2004-2006
+ * Tiled Map Editor, (c) 2004-2008
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -12,153 +12,364 @@
package tiled.view;
+// for console logging
+import java.util.logging.*;
+import java.io.IOException;
+
import java.awt.*;
-import java.awt.geom.Point2D;
+import java.awt.geom.*;
+
import javax.swing.SwingConstants;
-import tiled.core.Map;
-import tiled.core.ObjectGroup;
-import tiled.core.Tile;
-import tiled.core.TileLayer;
+import tiled.core.*;
+//import tiled.io.TiledLogger;
import tiled.mapeditor.selection.SelectionLayer;
/**
* A View for displaying Hex based maps.
- * The Hexs are layed out horizontally (i.e. the pointy sides are on the sides
- * and the flat sides are on the bottom).
+ * There are four possible layouts for the hexes. These are called
+ * tile alignment and are named 'top', 'bottom', 'left' and 'right'.
+ * The name designates the border where the first row or column of
+ * hexes is aligned with a flat side. I.e. 'left' and 'right' result
+ * in hexes with the pointy sides up and down and the first row
+ * either aligned left or right:
* <pre>
- * ___
- * e.g. / \
- * \---/
+ * /\
+ * | |
+ * \/
* </pre>
+ * And 'top' and 'bottom' result in hexes with the pointy sides to
+ * the left and right and the first column either aligned top or bottom:
+ * <pre>
+ * __
+ * / \
+ * \__/
*
- * Even numbered columns are staggered downwards by half a hex.
+ * </pre>
+
+ * <p>Here is an example 2x2 map with top alignment:
* <pre>
- * e.g.
- * 1,0 3,0
- * 0,0 2,0 4,0
- * 1,1 3,1
- * 0,1 2,1 4,1
+ * ___
+ * /0,0\___
+ * \___/1,0\
+ * /0,1\___/
+ * \___/1,1\
+ * \___/
* </pre>
*
- * <p>The icon width (as returned by Map.getTileWidth()) refers to the total
- * width of a hex (i.e from the left most corner to the right most corner). The
- * actual distance between two adjacent hexes is equal to 3/4 of this figure.
+ * <p>The icon width and height refer to the total width and height
+ * of a hex (i.e the size of the enclosing rectangle).
*
- * <p>The icon height (as returned by Map.getTileHeight()) refers to the total
- * height of a hex (i.e. from the bottom edge to the top edge).
- * This is equal to the distance between two adjacent hexes (in the same
- * column)
- *
* @version $Id$
*/
public class HexMapView extends MapView
{
+ public static final int ALIGN_TOP = 1;
+ public static final int ALIGN_BOTTOM = 2;
+ public static final int ALIGN_RIGHT = 3;
+ public static final int ALIGN_LEFT = 4;
+
private static final double HEX_SLOPE = Math.tan(Math.toRadians(60));
+ private int mapAlignment;
+ /* hexEdgesToTheLeft:
+ * This means a layout like this: __
+ * / \
+ * \__/
+ * as opposed to this: /\
+ * | |
+ * \/
+ */
+ private boolean hexEdgesToTheLeft;
+ private boolean alignedToBottomOrRight;
+
/**
* Creates a new hexagonal map view that displays the specified map.
*
- * @param map the map to be displayed by this map view
+ * @param map The map to be displayed by this map view.
*/
public HexMapView(Map map) {
super(map, null);
+
+ //mapAlignment = map.getAlignment();
+ mapAlignment = ALIGN_TOP;
+ hexEdgesToTheLeft = false;
+ if ( mapAlignment == ALIGN_TOP
+ || mapAlignment == ALIGN_BOTTOM ) {
+ hexEdgesToTheLeft = true;
+ }
+ alignedToBottomOrRight = false;
+ if ( mapAlignment == ALIGN_BOTTOM
+ || mapAlignment == ALIGN_RIGHT ) {
+ alignedToBottomOrRight = true;
+ }
+
+ //TiledLogger.getLogger().info("HexMapView created");
}
+ /**
+ * The scroll increment when clicking in the trough of a scrollbar,
+ * that is scrolling a page. The amount is set to the size
+ * of the completely visible hexes in the viewport.
+ *
+ * @param visibleRect Current viewport rectangle.
+ * @param orientation SwingConstants.VERTICAL or HORIZONTAL.
+ * @param direction > 0 = scrolling down; < 0 = scrolling up.
+ *
+ * @return Scroll amount in pixels.
+ */
public int getScrollableBlockIncrement(Rectangle visibleRect,
int orientation, int direction) {
- Dimension tsize = getTileSize();
+ Dimension tsize = getEffectiveTileSize();
+ int border = showGrid ? 1 : 0;
+ int tq = getThreeQuarterHex();
+ int hWidth = (int)(tsize.width / 2 + 0.49) + border;
+ int hHeight = (int)(tsize.height / 2 + 0.49) + border;
- if (orientation == SwingConstants.VERTICAL) {
- return (visibleRect.height / tsize.height) * tsize.height;
+ //TiledLogger.getLogger().info(
+ // "ScrollBlock " + orientation + "/" + direction);
+ //TiledLogger.getLogger().info(
+ // "visibleRect " + visibleRect.width + "," + visibleRect.height );
+ //TiledLogger.getLogger().info(
+ // "tq " + tq + " border " + border + " height " + tsize.height);
+ //TiledLogger.getLogger().info(
+ // "BlockInc w "
+ // + ((int)(visibleRect.width / (tq + border)) * (tq + border))
+ // + ", h "
+ // + ((int)(visibleRect.height / (tsize.height + border))
+ // * (tsize.height + border)));
+
+ if (orientation == SwingConstants.VERTICAL ) {
+ if ( hexEdgesToTheLeft ) {
+ return (int)((visibleRect.height - hHeight)
+ / (tsize.height + border))
+ * (tsize.height + border);
+ } else {
+ return (int)((visibleRect.height -hHeight) / (tq + border))
+ * (tq + border);
+ }
} else {
- return (visibleRect.width / tsize.width) * tsize.width;
+ if ( hexEdgesToTheLeft ) {
+ return (int)((visibleRect.width - hWidth) / (tq + border))
+ * (tq + border);
+ } else {
+ return (int)((visibleRect.width - hWidth)
+ / (tsize.width + border))
+ * (tsize.width + border);
+ }
}
}
+ /**
+ * The scroll increment when clicking on the arrows of a scrollbar,
+ * that is scrolling one hex horizontically or vertically.
+ *
+ * @param visibleRect Current viewport rectangle.
+ * @param orientation SwingConstants.VERTICAL or HORIZONTAL.
+ * @param direction > 0 = scrolling down; < 0 = scrolling up.
+ *
+ * @return Scroll amount in pixels.
+ */
public int getScrollableUnitIncrement(Rectangle visibleRect,
int orientation, int direction) {
- Dimension tsize = getTileSize();
- if (orientation == SwingConstants.VERTICAL) {
- return tsize.height;
+ //TiledLogger.getLogger().info(
+ // "ScrollUnit " + orientation + "/" + direction);
+ Dimension tsize = getEffectiveTileSize();
+ int border = showGrid ? 1 : 0;
+ int tq = getThreeQuarterHex();
+ if (orientation == SwingConstants.VERTICAL ) {
+ if ( hexEdgesToTheLeft ) {
+ return tsize.height + border;
+ } else {
+ return tq + border;
+ }
} else {
- return tsize.width;
+ if ( hexEdgesToTheLeft ) {
+ return tq + border;
+ } else {
+ return tsize.width + border;
+ }
}
}
+ /**
+ * The total size of the viewport so that all tiles of
+ * the map fit in.
+ *
+ * @return Width and Height as Dimension.
+ */
public Dimension getPreferredSize() {
- Dimension tsize = getTileSize();
+ Dimension tsize = getEffectiveTileSize();
+ int w;
+ int h;
int border = showGrid ? 1 : 0;
- int wbhc = (int) getWidthBetweenHexCentres();
+ int tq = getThreeQuarterHex();
+ int oq = getOneQuarterHex();
- return new Dimension(
- map.getWidth() * wbhc + border + wbhc,
- map.getHeight() * tsize.height + border +
- tsize.height / 2);
+ if ( hexEdgesToTheLeft ) {
+ //TiledLogger.getLogger().info(
+ // " twidth*3/4 " + tq
+ // + " twidth/4 " + oq
+ // + " theight/2 " + ((int)(tsize.height / 2 + 0.49)));
+
+ w = map.getWidth() * (tq + border) + oq + border;
+ h = map.getHeight() * (tsize.height + border)
+ + (int)(tsize.height / 2 + 0.49) + border;
+ } else {
+ w = map.getWidth() * (tsize.width + border)
+ + (int)(tsize.width / 2 + 0.49) + border;
+ h = map.getHeight() * (tq + border) + oq + border;
+ }
+
+ //TiledLogger.getLogger().info("size " + w + "," + h);
+
+ return new Dimension(w, h);
}
+ /**
+ * Paint one layer to the viewport.
+ *
+ * @param g2d The graphics context, i.e. where to paint.
+ * @param layer The layer to paint. Can be a special layer
+ * like the selection layer.
+ */
protected void paintLayer(Graphics2D g2d, TileLayer layer) {
// Determine area to draw from clipping rectangle
- Dimension tsize = getTileSize();
- int toffset = showGrid ? 1 : 0;
+ Dimension tsize = getEffectiveTileSize();
+ // int toffset = showGrid ? 1 : 0;
Rectangle clipRect = g2d.getClipBounds();
- int startX = clipRect.x / tsize.width;
- int startY = clipRect.y / tsize.height - 1;
- int endX = (int)(((clipRect.x + clipRect.width) / tsize.width) * 1.5) + 2;
- int endY = ((clipRect.y + clipRect.height) / tsize.height) * 3 + 2;
- int gy = startY * tsize.height + toffset;
- for (int y = startY; y < endY; y++) {
- Polygon gridPoly = createGridPolygon(0, y, 1);
- gridPoly.translate(0, -(int)(tsize.getHeight() / 2));
- int gx = startX * tsize.width + toffset;
- for (int x = startX; x < endX; x++) {
+ //TiledLogger.getLogger().info("clip " + clipRect.x + "," + clipRect.y
+ // + "-" + clipRect.width + "," + clipRect.height);
+
+ Point topLeft = screenToTileCoords(
+ (int)clipRect.getMinX(), (int)clipRect.getMinY());
+ Point bottomRight = screenToTileCoords(
+ (int)clipRect.getMaxX(), (int)clipRect.getMaxY());
+ int startX = (int)topLeft.getX();
+ int startY = (int)topLeft.getY();
+ int endX = (int)(bottomRight.getX());
+ int endY = (int)(bottomRight.getY());
+ if ( startX < 0 ) {
+ startX = 0;
+ }
+ if ( startY < 0 ) {
+ startY = 0;
+ }
+ if ( endX >= map.getWidth()) {
+ endX = map.getWidth() - 1;
+ }
+ if ( endY >= map.getHeight()) {
+ endY = map.getHeight() - 1;
+ }
+
+ //TiledLogger.getLogger().info("index " + startX + "," + startY
+ // + "-" + endX + "," + endY);
+
+ Polygon gridPoly;
+ double gx;
+ double gy;
+ for (int y = startY; y <= endY; y++) {
+ for (int x = startX; x <= endX; x++) {
Tile t = layer.getTileAt(x, y);
if (t != null) {
if (layer.getClass() == SelectionLayer.class) {
+ //TiledLogger.getLogger().info(
+ // "selection tile at " + x + "," + y);
+ gridPoly = createGridPolygon(x, y, 0);
g2d.fillPolygon(gridPoly);
} else {
- t.draw(g2d, gx, (int)(gy + (tsize.getHeight() / 2) *
- (1 - x % 2)), zoom);
+ Point screenCoords = getTopLeftCornerOfTile(x, y);
+ gx = screenCoords.getX();
+ gy = screenCoords.getY();
+ //TiledLogger.getLogger().info(
+ // "image tile at " + x + "," + y
+ // + " at " + gx + "," + gy);
+ t.draw(g2d, (int)gx, (int)(gy + tsize.height),
+ zoom);
}
}
- if (x % 2 == 0) {
- gridPoly.translate(
- (int)(tsize.getWidth() * .75),
- -(int)(tsize.getHeight() / 2));
- } else {
- gridPoly.translate(
- (int)(tsize.getWidth() * .75),
- (int)(tsize.getHeight() / 2));
- }
- gx += tsize.getWidth() * .75;
}
- gy += tsize.getHeight();
}
}
- protected void paintObjectGroup(Graphics2D g2d, ObjectGroup og) {
+ /**
+ * Paint one layer to the viewport. Is this function used?
+ * Not implemented!
+ *
+ * @param g2d The graphics context, i.e. where to paint.
+ * @param og What is that?
+ */
+ protected void paintLayer(Graphics2D g2d, ObjectGroup og) {
+ //TiledLogger.getLogger().info("called ?");
}
/**
- * Returns the distance between the centres of two horizontally adjacent
- * Hexes.
+ * @return The tile size in the view without border as Dimension.
*/
- private double getWidthBetweenHexCentres() {
- return map.getTileWidth() * 3 / 4;
+ private Dimension getEffectiveTileSize() {
+ //TiledLogger.getLogger().info("size "
+ // + ((int)(map.getTileWidth() * zoom + 0.999)) + ","
+ // + ((int)(map.getTileHeight() * zoom + 0.999)));
+ return new Dimension((int)(map.getTileWidth() * zoom + 0.999),
+ (int)(map.getTileHeight() * zoom + 0.999));
}
- private Dimension getTileSize() {
- return new Dimension(
- (int)(map.getTileWidth() * zoom),
- (int)(map.getTileHeight() * zoom));
+ /**
+ * Together with getOneQuarterHex this gives the sizes of
+ * one and three quarters in pixels in the interesting dimension.
+ * If the layout is such that the hex edges point left and right
+ * the interesting dimension is the width, otherwise it is the height.
+ * The sum of one and three quarters equals always the total size
+ * of the hex in this dimension.
+ *
+ * @return Three quarter of the tile size width or height (see above)
+ * as integer.
+ */
+ private int getThreeQuarterHex() {
+ int tq;
+ if ( hexEdgesToTheLeft ) {
+ tq = (int)(getEffectiveTileSize().width * 3.0 / 4.0 + 0.49);
+ } else {
+ tq = (int)(getEffectiveTileSize().height * 3.0 / 4.0 + 0.49);
+ }
+
+ return tq;
}
+ /**
+ * Together with getThreeQuarterHex this gives the sizes of
+ * one and three quarters in pixels in the interesting dimension.
+ * If the layout is such that the hex edges point left and right
+ * the interesting dimension is the width, otherwise it is the height.
+ * The sum of one and three quarters equals always the total size
+ * of the hex in this dimension.
+ *
+ * @return One quarter of the tile size width or height (see above)
+ * as integer.
+ */
+ private int getOneQuarterHex() {
+ int oq;
+ if ( hexEdgesToTheLeft ) {
+ oq = getEffectiveTileSize().width;
+ } else {
+ oq = getEffectiveTileSize().height;
+ }
+
+ return oq - getThreeQuarterHex();
+ }
+
+ /**
+ * Paint the grid to the viewport.
+ *
+ * @param g2d The graphics context, i.e. where to paint.
+ */
protected void paintGrid(Graphics2D g2d) {
g2d.setColor(Color.black);
- Dimension tileSize = getTileSize();
+ Dimension tileSize = getEffectiveTileSize();
+
// Determine area to draw from clipping rectangle
Rectangle clipRect = g2d.getClipBounds();
Point topLeft = screenToTileCoords(
@@ -167,166 +378,325 @@
(int)clipRect.getMaxX(), (int)clipRect.getMaxY());
int startX = (int)topLeft.getX();
int startY = (int)topLeft.getY();
- int endX = (int)(bottomRight.getX() * 1.5) + 1;
- int endY = (int)bottomRight.getY() * 2 + 1;
+ int endX = (int)(bottomRight.getX());
+ int endY = (int)(bottomRight.getY());
+
+ //TiledLogger.getLogger().info(
+ // " scrn " + clipRect.getMinX() + "," + clipRect.getMinY()
+ // + "-" + clipRect.getMaxX() + "," + clipRect.getMaxY());
+ //TiledLogger.getLogger().info(
+ // " tile " + startX + "," + startY + "-" + endX + "," + endY);
+
+ if ( startX < 0 ) {
+ startX = 0;
+ }
+ if ( startY < 0 ) {
+ startY = 0;
+ }
+ if ( endX >= map.getWidth()) {
+ endX = map.getWidth() - 1;
+ }
+ if ( endY >= map.getHeight()) {
+ endY = map.getHeight() - 1;
+ }
+
+ //TiledLogger.getLogger().info(" tile " + startX + "," + startY
+ // + "-" + endX + "," + endY);
+
int dy = 0;
+ int dx = 0;
Polygon grid;
- for (int y = startY; y < endY; y++, dy += tileSize.getHeight()) {
- grid = createGridPolygon(0, 0, 1);
- grid.translate(0,dy);
- for (int x = startX; x < endX; x++) {
- grid.translate(0,
- (int)((tileSize.getHeight() / 2) * (1 - x % 2)));
- g2d.drawPolygon(grid);
- grid.translate((int)(tileSize.getWidth() * .75), 0);
- grid.translate(0,
- -(int)((tileSize.getHeight() / 2) * (1 - x % 2)));
+ if ( hexEdgesToTheLeft ) {
+ for (int x = startX; x <= endX; x++) {
+ grid = createGridPolygon(x, startY, 1);
+ for (int y = startY; y <= endY; y++) {
+ g2d.drawPolygon(grid);
+ grid.translate(0, tileSize.height + 1);
+ }
}
+ } else {
+ for (int y = startY; y <= endY; y++) {
+ grid = createGridPolygon(startX, y, 1);
+ for (int x = startX; x <= endX; x++) {
+ g2d.drawPolygon(grid);
+ grid.translate(tileSize.width + 1, 0);
+ }
+ }
}
}
+ /**
+ * Paint coordinates.
+ * This should draw tiny coordinates in every hex tile.
+ * Not implemented.
+ *
+ * @param g2d The graphics context, i.e. where to paint.
+ */
protected void paintCoordinates(Graphics2D g2d) {
// TODO: Implement paintCoordinates for HexMapView
+ //TiledLogger.getLogger().info("NOT IMPLEMENTED");
}
- protected void paintPropertyFlags(Graphics2D g2d, TileLayer layer) {
- throw new RuntimeException("Not yet implemented"); // todo
- }
-
+ /**
+ * Compute the resulting tile coords, i.e. map coordinates,
+ * from a point in the viewport. This function works for some
+ * coords off the map, i.e. it works for the tile coord -1
+ * and for coords larger than the map size.
+ *
+ * @param screenX The x coordinate of a point in the viewport.
+ * @param screenY The y coordinate of a point in the viewport.
+ *
+ * @return The corresponding tile coords as Point.
+ */
public Point screenToTileCoords(int screenX, int screenY) {
- // An algorithm copied from the net years ago
- // Note the C style short variable names :-)
- int x = (int)(screenX / zoom);
- int y = (int)(screenY / zoom);
- double hexWidth = getWidthBetweenHexCentres();
- double hexHeight = map.getTileHeight();
+ //TiledLogger.getLogger().info(
+ // "screen coords " + screenX + "," + screenY);
- double tw = hexWidth * 2 / 3;
- double cw = hexWidth / 3;
+ int tx = 0;
+ int ty = 0;
+ int border = showGrid ? 1 : 0;
+ Dimension tileSize = getEffectiveTileSize();
+ int tileWidth = tileSize.width + border;
+ int tileHeight = tileSize.height + border;
+ int hWidth = (int)(tileWidth / 2 + 0.49) + border;
+ int hHeight = (int)(tileHeight / 2 + 0.49) + border;
+ Point [] fourPoints = new Point [4];
+ Point [] fourTiles = new Point [4];
- int adjustyhexes = 10;
+ int x = screenX;
+ int y = screenY;
- // Note: We adjust my & mx so they are always positive.
- // The algorithm returns incorrect values for negative my
- // The value adjustyhexes is arbitrary.
- // my is only ever negative for offboard hexes at the top of the map
- // We adjust it back further down
- int my = (int)(y + hexHeight * adjustyhexes);
- int mx = (int)(x + cw + hexWidth * adjustyhexes);
- int tx = (int)(mx / hexWidth);
- int rx = (int)(mx % hexWidth);
+ // determine the two columns of hexes we are between
+ // we are between col and col+1.
+ // col == -1 means we are in the strip to the left
+ // of the centers of the hexes of column 0.
+ int col = 0;
+ if ( x < hWidth ) {
+ col = -1;
+ } else {
+ if ( hexEdgesToTheLeft ) {
+ col = (int)((x - hWidth)
+ / (double)(getThreeQuarterHex() + border) + 0.001);
+ } else {
+ col = (int)((x - hWidth) / (double)tileWidth + 0.001);
+ }
+ }
- if (tx % 2 == 1) {
- my += hexHeight / 2;
+ // determine the two rows of hexes we are between
+ int row = 0;
+ if ( y < hHeight ) {
+ row = -1;
+ } else {
+ if ( hexEdgesToTheLeft ) {
+ row = (int)((y - hHeight) / (double)tileHeight + 0.001);
+ } else {
+ row = (int)((y - hHeight)
+ / (double)(getThreeQuarterHex() + border) + 0.001);
+ }
}
- int ty = (int)(my / hexHeight);
- int ry = (int)(my % hexHeight);
+ //TiledLogger.getLogger().info(" columns " + col + "/" + (col + 1));
+ //TiledLogger.getLogger().info(" rows " + row + "/" + (row + 1));
- if (rx > tw) {
- double newX = rx - tw;
- double height = (cw - newX) * HEX_SLOPE;
- if (ry < hexHeight / 2 - height) {
- tx++;
- if (tx % 2 == 0) {
- ty--;
- }
+ // now take the four surrounding points and
+ // find the one having the minimum distance to x,y
+ fourTiles [0] = new Point(col, row);
+ fourTiles [1] = new Point(col, row + 1);
+ fourTiles [2] = new Point(col + 1, row);
+ fourTiles [3] = new Point(col + 1, row + 1);
+
+ fourPoints [0] = tileToScreenCoords(col, row);
+ fourPoints [1] = tileToScreenCoords(col, row + 1);
+ fourPoints [2] = tileToScreenCoords(col + 1, row);
+ fourPoints [3] = tileToScreenCoords(col + 1, row + 1);
+
+ // find point with min.distance
+ double minDist = 2 * (map.getTileWidth() + map.getTileHeight());
+ int minI = 5;
+ //TiledLogger.getLogger().info(" init Min " + minDist);
+ for ( int i = 0; i < fourPoints.length; i++ ) {
+ if ( fourPoints [i].distance(x, y) < minDist ) {
+ minDist = fourPoints [i].distance(x, y);
+ minI = i;
}
- if (ry > hexHeight / 2 + height) {
- tx++;
- if (tx % 2 == 1) {
- ty++;
- }
- }
+
+ //TiledLogger.getLogger().info(" min.pt " + fourPoints [minI].getX()
+ // + "," + fourPoints [minI].getY() + " index " + minI
+ // + " at dist " + minDist);
}
- // Adjust back (see above)
- ty -= adjustyhexes;
- tx -= adjustyhexes;
+ // get min point
+ tx = (int)(fourTiles [minI].getX());
+ ty = (int)(fourTiles [minI].getY());
+ //TiledLogger.getLogger().info(" -> tile coords " + tx + "," + ty);
+
return new Point(tx, ty);
}
- public Point screenToPixelCoords(int x, int y) {
- // TODO: add proper implementation
- return new Point();
- }
-
/**
- * Get the point at the top left corner of the bounding rectangle of this
- * hex.
+ * Get the height of a tile of the map.
+ * I do not know why this function is here.
+ *
+ * @return The tile height as double.
*/
- private Point2D getTopLeftCornerOfHex(int x, int y) {
- Dimension tileSize = getTileSize();
- Point2D centre = tileToScreenCoords(x, y);
- double leftX = centre.getX() - tileSize.getWidth() / 2;
- double topY = centre.getY() - tileSize.getHeight() / 2;
- return new Point2D.Double(leftX, topY);
- }
-
private double getTileHeight() {
return map.getTileHeight();
}
+ /**
+ * Repaint a region of the viewport.
+ * This function has been disabled. I have tried it
+ * but it seems to repaint with some offset.
+ *
+ * @param The rectangle of the viewport to be repainted.
+ */
public void repaintRegion(Rectangle region) {
super.repaintRegion(region);
- // This code should work. I've disabled it because of general problems with the view refresh.
- // Point2D topLeft=getTopLeftCornerOfHex((int) region.getMinX(),(int) region.getMinY(),zoom);
- // Point2D bottomRight=getTopLeftCornerOfHex((int) region.getMaxX(),(int) region.getMaxY(),zoom);
- //
- // Dimension tileSize=getTileSize(zoom);
- // int width=(int) (bottomRight.getX()-topLeft.getX()+tileSize.getWidth());
- // int height=(int) (bottomRight.getY()-topLeft.getY()+tileSize.getHeight());
- //
- // Rectangle dirty=new Rectangle((int) topLeft.getX(),(int) topLeft.getY(),width,height);
- //
- // repaint(dirty);
+
+ //TiledLogger.getLogger().info(
+ // "region " + region.getMinX() + "," + region.getMinY()
+ // + "-" + region.getMaxX() + "," + region.getMaxY()
+ // + " zoom " + zoom);
+
+ // // This code should work. I've disabled it because of general problems with the view refresh.
+ // // Point2D topLeft=getTopLeftCornerOfTile((int) region.getMinX(),(int) region.getMinY(),zoom);
+ // // Point2D bottomRight=getTopLeftCornerOfTile((int) region.getMaxX(),(int) region.getMaxY(),zoom);
+ // Point2D topLeft=getTopLeftCornerOfTile((int) region.getMinX(),(int) region.getMinY());
+ // Point2D bottomRight=getTopLeftCornerOfTile((int) region.getMaxX(),(int) region.getMaxY());
+ //
+ // // Dimension tileSize=getTileSize(zoom);
+ // Dimension tileSize=getTileSize();
+ // int width=(int) (bottomRight.getX()-topLeft.getX()+tileSize.getWidth());
+ // int height=(int) (bottomRight.getY()-topLeft.getY()+tileSize.getHeight());
+ //
+ // Rectangle dirty=new Rectangle((int) topLeft.getX(),(int) topLeft.getY(),width,height);
+ //
+ // repaint(dirty);
}
+ /**
+ * Returns a hexagon at the given tile coordinates.
+ *
+ * @param tx The x coordinate of the tile.
+ * @param ty The y coordinate of the tile.
+ * @param border 0 = no border, 1 = with border line.
+ *
+ * @return A hexagon structure as Polygon.
+ */
protected Polygon createGridPolygon(int tx, int ty, int border) {
- double centrex, centrey;
- Dimension tileSize = getTileSize();
+ Dimension tileSize = getEffectiveTileSize();
Polygon poly = new Polygon();
+ Point p = getTopLeftCornerOfTile(tx, ty);
+ int topLeftX = (int)(p.getX());
+ int topLeftY = (int)(p.getY());
- centrex = tx*tileSize.getWidth() + tileSize.getWidth() / 2;
- centrey = ty*tileSize.getHeight() + tileSize.getHeight() / 2;
+ //TiledLogger.getLogger().info("hex at " + topLeftX + "," + topLeftY);
+ int tq = getThreeQuarterHex();
+ int oq = getOneQuarterHex();
+
// Go round the sides clockwise
- poly.addPoint(
- (int)(centrex - tileSize.getWidth() / 2),
- (int)centrey);
- poly.addPoint(
- (int)(centrex - tileSize.getWidth() / 4),
- (int)(centrey - tileSize.getHeight() / 2));
- poly.addPoint(
- (int)(centrex + tileSize.getWidth() / 4),
- (int)(centrey - tileSize.getHeight() / 2));
- poly.addPoint(
- (int)(centrex + tileSize.getWidth() / 2),
- (int)centrey);
- poly.addPoint(
- (int)(centrex + tileSize.getWidth() / 4),
- (int)(centrey + tileSize.getHeight() / 2));
- poly.addPoint(
- (int)(centrex - tileSize.getWidth() / 4),
- (int)(centrey + tileSize.getHeight() / 2));
+ if ( hexEdgesToTheLeft ) {
+ int hh = (int)(tileSize.height / 2 + 0.49);
+ poly.addPoint(topLeftX - 1, topLeftY + hh - 1);
+ poly.addPoint(topLeftX + oq - 1, topLeftY - 1);
+ poly.addPoint(topLeftX + tq, topLeftY - 1);
+ poly.addPoint(topLeftX + tileSize.width, topLeftY + hh - 1);
+ poly.addPoint(topLeftX + tq, topLeftY + tileSize.height);
+ poly.addPoint(topLeftX + oq - 1, topLeftY + tileSize.height);
+ } else {
+ int hh = (int)(tileSize.width / 2 + 0.49);
+
+ poly.addPoint(topLeftX + hh - 1, topLeftY - 1);
+ poly.addPoint(topLeftX + tileSize.width, topLeftY + oq - 1);
+ poly.addPoint(topLeftX + tileSize.width, topLeftY + tq);
+ poly.addPoint(topLeftX + hh - 1, topLeftY + tileSize.height);
+ poly.addPoint(topLeftX - 1, topLeftY + tq);
+ poly.addPoint(topLeftX - 1, topLeftY + oq - 1);
+ }
+
return poly;
}
/**
- * Returns the location on screen for the given tile.
+ * Get the point at the top left corner of the bounding rectangle of this
+ * hex.
*
- * @return The point at the centre of the Hex.
+ * @param x The x coordinate of the tile.
+ * @param y The y coordinate of the tile.
+ *
+ * @return The top left corner of the enclosing rectangle of the hex
+ * in screen coordinates as Point.
*/
- public Point tileToScreenCoords(double x, double y) {
- double xx = getWidthBetweenHexCentres() * x;
- double yy = getTileHeight() * y;
- if (x % 2 == 0) {
- yy += getTileHeight() / 2;
+ private Point getTopLeftCornerOfTile(int x, int y) {
+ //TiledLogger.getLogger().info("tile coords " + x + "," + y);
+
+ Dimension tileSize = getEffectiveTileSize();
+ int w = tileSize.width;
+ int h = tileSize.height;
+ int xx;
+ int yy;
+
+ if ( hexEdgesToTheLeft ) {
+ xx = x * getThreeQuarterHex();
+ yy = y * h;
+ } else {
+ xx = x * w;
+ yy = y * getThreeQuarterHex();
}
- return new Point((int)(xx * zoom), (int)(yy * zoom));
+
+ if ( showGrid ) {
+ xx += x + 1;
+ yy += y + 1;
+ }
+
+ if ((Math.abs(x % 2) == 1 && mapAlignment == ALIGN_TOP)
+ || (x % 2 == 0 && mapAlignment == ALIGN_BOTTOM)) {
+ yy += (int)(h / 2.0 + 0.49);
+ }
+ if ((Math.abs(y % 2) == 1 && mapAlignment == ALIGN_LEFT)
+ || (y % 2 == 0 && mapAlignment == ALIGN_RIGHT)) {
+ xx += (int)(w / 2.0 + 0.49);
+ }
+
+ //TiledLogger.getLogger().info(
+ // " -> screen coords " + xx + "," + yy + " zoom " + zoom);
+
+ return new Point(xx, yy);
}
+
+ /**
+ * Returns the location (center) on screen for the given tile.
+ * Works also for hypothetical tiles off the map.
+ * The zoom is accounted for.
+ *
+ * @param x The x coordinate of the tile.
+ * @param y The y coordinate of the tile.
+ *
+ * @return The point at the centre of the Hex as Point.
+ */
+ public Point tileToScreenCoords(double x, double y) {
+ Point p = getTopLeftCornerOfTile((int)x, (int)y);
+ Dimension tileSize = getEffectiveTileSize();
+ return new Point(
+ (int)(p.getX()) + (int)(tileSize.width / 2 + 0.49),
+ (int)(p.getY()) + (int)(tileSize.height / 2 + 0.49));
+ }
+
+ public Point screenToPixelCoords(int x, int y) {
+ // TODO: add proper implementation
+ return new Point();
+ }
+
+ protected void paintPropertyFlags(Graphics2D g2d, TileLayer layer) {
+ throw new RuntimeException("Not yet implemented"); // todo
+ }
+
+ protected void paintObjectGroup(Graphics2D g2d, ObjectGroup og) {
+ // TODO: Implement objectgroup painting for HexMapView
+ }
}
More information about the tiled-commit
mailing list