Skip to content

Commit

Permalink
Added support for flat-top hexagonal (staggering the X axis)
Browse files Browse the repository at this point in the history
This also adds support for staggering the X axis at either odd or
even indexes for staggered isometric maps.
  • Loading branch information
bjorn committed Nov 6, 2014
1 parent da2c2e0 commit 915fd32
Show file tree
Hide file tree
Showing 14 changed files with 483 additions and 220 deletions.
448 changes: 315 additions & 133 deletions src/libtiled/hexagonalrenderer.cpp

Large diffs are not rendered by default.

32 changes: 26 additions & 6 deletions src/libtiled/hexagonalrenderer.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,15 +49,35 @@ class TILEDSHARED_EXPORT HexagonalRenderer : public OrthogonalRenderer
{
RenderParams(const Map *map);

bool stagger(int index) const { return (index & 1) ^ staggerEven; }
bool stagger(int x, int y) const
{
if (staggerX)
return (x & 1) ^ staggerEven;
else
return (y & 1) ^ staggerEven;
}

bool stagger(const QPoint &point) const
{
return stagger(point.x(), point.y());
}

bool doStaggerX(int x) const
{ return staggerX && (x & 1) ^ staggerEven; }

bool doStaggerY(int y) const
{ return !staggerX && (y & 1) ^ staggerEven; }

const int tileWidth;
const int tileHeight;
const int halfTileWidth;
const int sideLength;
const int sideOffset;
const int rowHeight;
const int staggerEven;
int sideLengthX;
int sideOffsetX;
int sideLengthY;
int sideOffsetY;
int rowHeight;
int columnWidth;
const bool staggerX;
const bool staggerEven;
};

public:
Expand Down
26 changes: 13 additions & 13 deletions src/libtiled/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Map::Map(Orientation orientation,
mTileWidth(tileWidth),
mTileHeight(tileHeight),
mHexSideLength(0),
mStaggerDirection(StaggerRows),
mStaggerAxis(StaggerY),
mStaggerIndex(StaggerOdd),
mLayerDataFormat(Base64Zlib)
{
Expand All @@ -63,7 +63,7 @@ Map::Map(const Map &map):
mTileWidth(map.mTileWidth),
mTileHeight(map.mTileHeight),
mHexSideLength(map.mHexSideLength),
mStaggerDirection(map.mStaggerDirection),
mStaggerAxis(map.mStaggerAxis),
mStaggerIndex(map.mStaggerIndex),
mBackgroundColor(map.mBackgroundColor),
mDrawMargins(map.mDrawMargins),
Expand Down Expand Up @@ -232,25 +232,25 @@ bool Map::isTilesetUsed(Tileset *tileset) const
}


QString Tiled::staggerDirectionToString(Map::StaggerDirection staggerDirection)
QString Tiled::staggerAxisToString(Map::StaggerAxis staggerAxis)
{
switch (staggerDirection) {
switch (staggerAxis) {
default:
case Map::StaggerColumns:
return QLatin1String("columns");
case Map::StaggerY:
return QLatin1String("y");
break;
case Map::StaggerRows:
return QLatin1String("rows");
case Map::StaggerX:
return QLatin1String("x");
break;
}
}

Map::StaggerDirection Tiled::staggerDirectionFromString(const QString &string)
Map::StaggerAxis Tiled::staggerAxisFromString(const QString &string)
{
Map::StaggerDirection staggerDirection = Map::StaggerColumns;
if (string == QLatin1String("rows"))
staggerDirection = Map::StaggerRows;
return staggerDirection;
Map::StaggerAxis staggerAxis = Map::StaggerY;
if (string == QLatin1String("x"))
staggerAxis = Map::StaggerX;
return staggerAxis;
}

QString Tiled::staggerIndexToString(Map::StaggerIndex staggerIndex)
Expand Down
36 changes: 18 additions & 18 deletions src/libtiled/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,12 @@ class TILEDSHARED_EXPORT Map : public Object
};

/**
* Whether the tiles are staggered by rows or columns. Only used by the
* isometric staggered and hexagonal map renderers.
* Which axis is staggered. Only used by the isometric staggered and
* hexagonal map renderers.
*/
enum StaggerDirection {
StaggerColumns,
StaggerRows
enum StaggerAxis {
StaggerX,
StaggerY
};

/**
Expand Down Expand Up @@ -149,22 +149,22 @@ class TILEDSHARED_EXPORT Map : public Object
{ mRenderOrder = renderOrder; }

/**
* Returns the width of this map.
* Returns the width of this map in tiles.
*/
int width() const { return mWidth; }

/**
* Sets the width of this map.
* Sets the width of this map in tiles.
*/
void setWidth(int width) { mWidth = width; }

/**
* Returns the height of this map.
* Returns the height of this map in tiles.
*/
int height() const { return mHeight; }

/**
* Sets the height of this map.
* Sets the height of this map in tiles.
*/
void setHeight(int height) { mHeight = height; }

Expand Down Expand Up @@ -201,8 +201,8 @@ class TILEDSHARED_EXPORT Map : public Object
int hexSideLength() const;
void setHexSideLength(int hexSideLength);

StaggerDirection staggerDirection() const;
void setStaggerDirection(StaggerDirection staggerDirection);
StaggerAxis staggerAxis() const;
void setStaggerAxis(StaggerAxis staggerAxis);

StaggerIndex staggerIndex() const;
void setStaggerIndex(StaggerIndex staggerIndex);
Expand Down Expand Up @@ -379,7 +379,7 @@ class TILEDSHARED_EXPORT Map : public Object
int mTileWidth;
int mTileHeight;
int mHexSideLength;
StaggerDirection mStaggerDirection;
StaggerAxis mStaggerAxis;
StaggerIndex mStaggerIndex;
QColor mBackgroundColor;
QMargins mDrawMargins;
Expand All @@ -399,14 +399,14 @@ inline void Map::setHexSideLength(int hexSideLength)
mHexSideLength = hexSideLength;
}

inline Map::StaggerDirection Map::staggerDirection() const
inline Map::StaggerAxis Map::staggerAxis() const
{
return mStaggerDirection;
return mStaggerAxis;
}

inline void Map::setStaggerDirection(StaggerDirection staggerDirection)
inline void Map::setStaggerAxis(StaggerAxis staggerAxis)
{
mStaggerDirection = staggerDirection;
mStaggerAxis = staggerAxis;
}

inline Map::StaggerIndex Map::staggerIndex() const
Expand All @@ -420,8 +420,8 @@ inline void Map::setStaggerIndex(StaggerIndex staggerIndex)
}


TILEDSHARED_EXPORT QString staggerDirectionToString(Map::StaggerDirection staggerDirection);
TILEDSHARED_EXPORT Map::StaggerDirection staggerDirectionFromString(const QString &);
TILEDSHARED_EXPORT QString staggerAxisToString(Map::StaggerAxis);
TILEDSHARED_EXPORT Map::StaggerAxis staggerAxisFromString(const QString &);

TILEDSHARED_EXPORT QString staggerIndexToString(Map::StaggerIndex staggerIndex);
TILEDSHARED_EXPORT Map::StaggerIndex staggerIndexFromString(const QString &);
Expand Down
10 changes: 5 additions & 5 deletions src/libtiled/mapreader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ Map *MapReaderPrivate::readMap()
.arg(orientationString));
}

const QString staggerDirectionString =
atts.value(QLatin1String("staggerdirection")).toString();
const Map::StaggerDirection staggerDirection =
staggerDirectionFromString(staggerDirectionString);
const QString staggerAxisString =
atts.value(QLatin1String("staggeraxis")).toString();
const Map::StaggerAxis staggerAxis =
staggerAxisFromString(staggerAxisString);

const QString staggerIndexString =
atts.value(QLatin1String("staggerindex")).toString();
Expand All @@ -240,7 +240,7 @@ Map *MapReaderPrivate::readMap()

mMap = new Map(orientation, mapWidth, mapHeight, tileWidth, tileHeight);
mMap->setHexSideLength(hexSideLength);
mMap->setStaggerDirection(staggerDirection);
mMap->setStaggerAxis(staggerAxis);
mMap->setStaggerIndex(staggerIndex);
mMap->setRenderOrder(renderOrder);
mCreatedTilesets.clear();
Expand Down
4 changes: 2 additions & 2 deletions src/libtiled/mapwriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,8 +186,8 @@ void MapWriterPrivate::writeMap(QXmlStreamWriter &w, const Map *map)
if (map->orientation() == Map::Hexagonal) {
w.writeAttribute(QLatin1String("hexsidelength"),
QString::number(map->hexSideLength()));
w.writeAttribute(QLatin1String("staggerdirection"),
staggerDirectionToString(map->staggerDirection()));
w.writeAttribute(QLatin1String("staggeraxis"),
staggerAxisToString(map->staggerAxis()));
}

if (map->orientation() == Map::Staggered || map->orientation() == Map::Hexagonal) {
Expand Down
40 changes: 25 additions & 15 deletions src/libtiled/staggeredrenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,36 @@ QPointF StaggeredRenderer::screenToTileCoords(qreal x, qreal y) const
{
const RenderParams p(map());

const int halfTileHeight = p.tileHeight / 2;
const qreal ratio = (qreal) p.tileHeight / p.tileWidth;
if (p.staggerX)
x -= p.staggerEven ? p.sideOffsetX : 0;
else
y -= p.staggerEven ? p.sideOffsetY : 0;

// Start with the coordinates of a grid-aligned tile
const int tileX = qFloor(x / p.tileWidth);
const int tileY = qFloor(y / p.tileHeight) * 2;
QPoint referencePoint = QPoint(qFloor(x / p.tileWidth),
qFloor(y / p.tileHeight));

// Relative x and y position on the base square of the grid-aligned tile
const qreal relX = x - tileX * p.tileWidth;
const qreal relY = y - (tileY / 2) * p.tileHeight;
const QPointF rel(x - referencePoint.x() * p.tileWidth,
y - referencePoint.y() * p.tileHeight);

// Adjust the reference point to the correct tile coordinates
int &staggerAxisIndex = p.staggerX ? referencePoint.rx() : referencePoint.ry();
staggerAxisIndex *= 2;
if (p.staggerEven)
++staggerAxisIndex;

const qreal y_pos = rel.x() * ((qreal) p.tileHeight / p.tileWidth);

// Check whether the cursor is in any of the corners (neighboring tiles)
if (halfTileHeight - relX * ratio > relY)
return topLeft(tileX, tileY);
if (-halfTileHeight + relX * ratio > relY)
return topRight(tileX, tileY);
if (halfTileHeight + relX * ratio < relY)
return bottomLeft(tileX, tileY);
if (halfTileHeight * 3 - relX * ratio < relY)
return bottomRight(tileX, tileY);
if (p.sideOffsetY - y_pos > rel.y())
return topLeft(referencePoint.x(), referencePoint.y());
if (-p.sideOffsetY + y_pos > rel.y())
return topRight(referencePoint.x(), referencePoint.y());
if (p.sideOffsetY + y_pos < rel.y())
return bottomLeft(referencePoint.x(), referencePoint.y());
if (p.sideOffsetY * 3 - y_pos < rel.y())
return bottomRight(referencePoint.x(), referencePoint.y());

return QPoint(tileX, tileY);
return referencePoint;
}
9 changes: 7 additions & 2 deletions src/libtiled/tilelayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,7 @@ class TILEDSHARED_EXPORT TileLayer : public Layer
* Returns a read-only reference to the cell at the given coordinates. The
* coordinates have to be within this layer.
*/
const Cell &cellAt(int x, int y) const
{ return mGrid.at(x + y * mWidth); }
const Cell &cellAt(int x, int y) const;

const Cell &cellAt(const QPoint &point) const
{ return cellAt(point.x(), point.y()); }
Expand Down Expand Up @@ -318,6 +317,12 @@ inline QRegion TileLayer::region() const
return region(cellInUse);
}

inline const Cell &TileLayer::cellAt(int x, int y) const
{
Q_ASSERT(contains(x, y));
return mGrid.at(x + y * mWidth);
}

} // namespace Tiled

#endif // TILELAYER_H
2 changes: 1 addition & 1 deletion src/plugins/json/maptovariantconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ QVariant MapToVariantConverter::toVariant(const Map *map, const QDir &mapDir)

if (map->orientation() == Map::Hexagonal) {
mapVariant["hexsidelength"] = map->hexSideLength();
mapVariant["staggerdirection"] = staggerDirectionToString(map->staggerDirection());
mapVariant["staggeraxis"] = staggerAxisToString(map->staggerAxis());
}

if (map->orientation() == Map::Hexagonal || map->orientation() == Map::Staggered)
Expand Down
6 changes: 3 additions & 3 deletions src/plugins/json/varianttomapconverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ Map *VariantToMapConverter::toMap(const QVariant &variant,
return 0;
}

const QString staggerDirectionString = variantMap["staggerdirection"].toString();
Map::StaggerDirection staggerDirection = staggerDirectionFromString(staggerDirectionString);
const QString staggerAxisString = variantMap["staggeraxis"].toString();
Map::StaggerAxis staggerAxis = staggerAxisFromString(staggerAxisString);

const QString staggerIndexString = variantMap["staggerindex"].toString();
Map::StaggerIndex staggerIndex = staggerIndexFromString(staggerIndexString);
Expand All @@ -76,7 +76,7 @@ Map *VariantToMapConverter::toMap(const QVariant &variant,
variantMap["tilewidth"].toInt(),
variantMap["tileheight"].toInt()));
map->setHexSideLength(variantMap["hexsidelength"].toInt());
map->setStaggerDirection(staggerDirection);
map->setStaggerAxis(staggerAxis);
map->setStaggerIndex(staggerIndex);
map->setRenderOrder(renderOrder);

Expand Down
30 changes: 23 additions & 7 deletions src/tiled/changemapproperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,16 @@ ChangeMapProperty::ChangeMapProperty(MapDocument *mapDocument,
{
}

ChangeMapProperty::ChangeMapProperty(MapDocument *mapDocument,
Map::StaggerAxis staggerAxis)
: QUndoCommand(QCoreApplication::translate("Undo Commands",
"Change Stagger Axis"))
, mMapDocument(mapDocument)
, mProperty(StaggerAxis)
, mStaggerAxis(staggerAxis)
{
}

ChangeMapProperty::ChangeMapProperty(MapDocument *mapDocument,
Map::StaggerIndex staggerIndex)
: QUndoCommand(QCoreApplication::translate("Undo Commands",
Expand Down Expand Up @@ -131,25 +141,31 @@ void ChangeMapProperty::swap()
mIntValue = tileHeight;
break;
}
case Orientation: {
const Map::Orientation orientation = map->orientation();
map->setOrientation(mOrientation);
mOrientation = orientation;
mMapDocument->createRenderer();
break;
}
case HexSideLength: {
const int hexSideLength = map->hexSideLength();
map->setHexSideLength(mIntValue);
mIntValue = hexSideLength;
break;
}
case StaggerAxis: {
const Map::StaggerAxis staggerAxis = map->staggerAxis();
map->setStaggerAxis(mStaggerAxis);
mStaggerAxis = staggerAxis;
break;
}
case StaggerIndex: {
const Map::StaggerIndex staggerIndex = map->staggerIndex();
map->setStaggerIndex(mStaggerIndex);
mStaggerIndex = staggerIndex;
break;
}
case Orientation: {
const Map::Orientation orientation = map->orientation();
map->setOrientation(mOrientation);
mOrientation = orientation;
mMapDocument->createRenderer();
break;
}
case RenderOrder: {
const Map::RenderOrder renderOrder = map->renderOrder();
map->setRenderOrder(mRenderOrder);
Expand Down
Loading

0 comments on commit 915fd32

Please sign in to comment.