Skip to content

Commit

Permalink
Fixed terrain brush for isometric staggered maps
Browse files Browse the repository at this point in the history
Also added an isometric staggered example map.

Closes mapeditor#427
  • Loading branch information
luyungeng authored and bjorn committed Jan 12, 2017
1 parent e6d8a32 commit 18d633b
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 20 deletions.
41 changes: 41 additions & 0 deletions examples/isometric_staggered_grass_and_water.tmx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="staggered" renderorder="right-down" width="25" height="50" tilewidth="64" tileheight="32" staggeraxis="y" staggerindex="odd" nextobjectid="1">
<tileset firstgid="1" name="isometric_grass_and_water" tilewidth="64" tileheight="64" tilecount="24" columns="4">
<tileoffset x="0" y="16"/>
<grid orientation="orthogonal" width="64" height="32"/>
<image source="isometric_grass_and_water.png" width="256" height="384"/>
<terraintypes>
<terrain name="Grass" tile="0"/>
<terrain name="Water" tile="22"/>
</terraintypes>
<tile id="0" terrain="0,0,0,0"/>
<tile id="1" terrain="0,0,0,0"/>
<tile id="2" terrain="0,0,0,0"/>
<tile id="3" terrain="0,0,0,0"/>
<tile id="4" terrain="0,0,0,1"/>
<tile id="5" terrain="0,0,1,0"/>
<tile id="6" terrain="1,0,0,0"/>
<tile id="7" terrain="0,1,0,0"/>
<tile id="8" terrain="0,1,1,1"/>
<tile id="9" terrain="1,0,1,1"/>
<tile id="10" terrain="1,1,1,0"/>
<tile id="11" terrain="1,1,0,1"/>
<tile id="12" terrain="0,0,1,1"/>
<tile id="13" terrain="1,0,1,0"/>
<tile id="14" terrain="1,1,0,0"/>
<tile id="15" terrain="0,1,0,1"/>
<tile id="16" terrain="0,0,1,1"/>
<tile id="17" terrain="1,0,1,0"/>
<tile id="18" terrain="1,1,0,0"/>
<tile id="19" terrain="0,1,0,1"/>
<tile id="20" terrain="0,1,1,0"/>
<tile id="21" terrain="1,0,0,1"/>
<tile id="22" terrain="1,1,1,1"/>
<tile id="23" terrain="1,1,1,1"/>
</tileset>
<layer name="Tile Layer 1" width="25" height="50">
<data encoding="base64" compression="zlib">
eJytl21zozAMhE0ghCOlpJAp+f+/9OIZ7fCwNaHt3QcNAduSdvXmPFJKj6csT7k+ZQ55i28PrF+ecgqpntLgvY73JtZq/Nb5LO+xlqULO7Ix2fkKe1237Gst+z6GXGz9DnzC4DYa7HdM2j8V9uhdWPKeM6ROW3/JHTFJ3gv88ncXGPLzT0hrPJXw8HsfZ9yXynSMERf5pP2Ukq+K+YQ90lkHL208B/BGH8UdfZIeiXzTmvSKp09w1Nu+nBMfoZ/nyF1+n4Nv+SL+G7wrh5fQ0yA+j7Cjc8xp6SRHzD3G4h66esR0NLvMM88rcj/E/ipt43pLa50OaZsHS9imvrPFQxhu8LXF98zBNa195QNxFpbB9IhP5kKV1pqmHfF1SWv/WiIOwqPvwn9La2547Lu07YPMUWFhf2zjO7nSPtljPVZmh/mstYxlDh1XxF/7hfuStn2PuVzDjvLZ8yx/+wy9A/iVP+wnFc76PKDvrCu939JaF3r25ov3qwrPGrqG0KGZcodOzhzxr3PMI+Lw2mSOKfZ3068c6MH/3eLN2ijFfkRclD/SPaW1NhTrm8WFPPlsYvyZGzNwqb+9gcsu1sg3+5Xzx34lWzN0NNApHRfsVz8mllP6is3npuq9xn6f//KnA49eJ6U7DfujzzDPV/Zk1ajPSuIo2dy79zivp4hVW7DxE/Gcpz9d2vb73whzxOMmTHs4zvZ8JV4Dytf8VK2UzmWM6nV7XHquMV5Zt2a7epifzzWQe9K0o1+547NBdb6EDfFUslGl9Q71iiOPO2e15uQrrrRWikmDNYnqWvr9jl8S9tDB1nTn0AzRXFddsxe/slEZt/zOGcK70Bz4eX8o1bjrEu7BbFP/A3Y0A3jXe4WB3LZm1/+/Ca96vd73ckpxXyB92vJXEvnSpS22PSxzgYculTHod184e9QP+V9TMeHd3eNBnaPZPeKKNVXCoH2aj7RxhGM0nZ5LLqpb9a0x7de5x+SavmJyrqSLM+RyoJ9YJsThuiP8X+x3aPWdvTzmveo9rXdll1c9UzV1hEd3HvVZ3pmPRPVytP+73O7VwHdwHIl6fGlNfelf9KrHDwU77Hu/saEer9rkf8T/YUNxLNVna3v0/S8kYST7
</data>
</layer>
</map>
59 changes: 39 additions & 20 deletions src/tiled/terrainbrush.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <math.h>
#include <QVector>
#include <climits>
#include <staggeredrenderer.h>

using namespace Tiled;
using namespace Tiled::Internal;
Expand Down Expand Up @@ -376,6 +377,24 @@ void TerrainBrush::updateBrush(QPoint cursorPos, const QVector<QPoint> *list)
if (checked[i])
continue;

// to support isometric staggered, make edges into variables
QPoint upPoint(x, y-1);
QPoint bottomPoint(x, y+1);
QPoint leftPoint(x-1, y);
QPoint rightPoint(x+1, y);

if (auto renderer = dynamic_cast<StaggeredRenderer*>(mapDocument()->renderer())) {
upPoint = renderer->topRight(x, y);
bottomPoint = renderer->bottomLeft(x, y);
leftPoint = renderer->topLeft(x, y);
rightPoint = renderer->bottomRight(x, y);
}

int upperIndex = upPoint.y()*layerWidth + upPoint.x();
int bottomIndex = bottomPoint.y()*layerWidth + bottomPoint.x();
int leftIndex = leftPoint.y()*layerWidth + leftPoint.x();
int rightIndex = rightPoint.y()*layerWidth + rightPoint.x();

const Tile *tile = currentLayer->cellAt(p).tile;
const unsigned currentTerrain = ::terrain(tile);

Expand Down Expand Up @@ -429,20 +448,20 @@ void TerrainBrush::updateBrush(QPoint cursorPos, const QVector<QPoint> *list)
mask = 0;

// depending which connections have been set, we update the preferred terrain of the tile accordingly
if (y > 0 && checked[i - layerWidth]) {
preferredTerrain = (::terrain(newTerrain[i - layerWidth]) << 16) | (preferredTerrain & 0x0000FFFF);
if (currentLayer->contains(upPoint) && checked[upperIndex]) {
preferredTerrain = (::terrain(newTerrain[upperIndex]) << 16) | (preferredTerrain & 0x0000FFFF);
mask |= 0xFFFF0000;
}
if (y < layerHeight - 1 && checked[i + layerWidth]) {
preferredTerrain = (::terrain(newTerrain[i + layerWidth]) >> 16) | (preferredTerrain & 0xFFFF0000);
if (currentLayer->contains(bottomPoint) && checked[bottomIndex]) {
preferredTerrain = (::terrain(newTerrain[bottomIndex]) >> 16) | (preferredTerrain & 0xFFFF0000);
mask |= 0x0000FFFF;
}
if (x > 0 && checked[i - 1]) {
preferredTerrain = ((::terrain(newTerrain[i - 1]) << 8) & 0xFF00FF00) | (preferredTerrain & 0x00FF00FF);
if (currentLayer->contains(leftPoint) && checked[leftIndex]) {
preferredTerrain = ((::terrain(newTerrain[leftIndex]) << 8) & 0xFF00FF00) | (preferredTerrain & 0x00FF00FF);
mask |= 0xFF00FF00;
}
if (x < layerWidth - 1 && checked[i + 1]) {
preferredTerrain = ((::terrain(newTerrain[i + 1]) >> 8) & 0x00FF00FF) | (preferredTerrain & 0xFF00FF00);
if (currentLayer->contains(rightPoint) && checked[rightIndex]) {
preferredTerrain = ((::terrain(newTerrain[rightIndex]) >> 8) & 0x00FF00FF) | (preferredTerrain & 0xFF00FF00);
mask |= 0x00FF00FF;
}
}
Expand All @@ -464,25 +483,25 @@ void TerrainBrush::updateBrush(QPoint cursorPos, const QVector<QPoint> *list)
brushRect |= QRect(p, p);

// consider surrounding tiles if terrain constraints were not satisfied
if (y > 0 && !checked[i - layerWidth]) {
const Tile *above = currentLayer->cellAt(x, y - 1).tile;
if (currentLayer->contains(upPoint) && !checked[upperIndex]) {
const Tile *above = currentLayer->cellAt(upPoint).tile;
if (topEdge(paste) != bottomEdge(above))
transitionList.append(QPoint(x, y - 1));
transitionList.append(upPoint);
}
if (y < layerHeight - 1 && !checked[i + layerWidth]) {
const Tile *below = currentLayer->cellAt(x, y + 1).tile;
if (currentLayer->contains(bottomPoint) && !checked[bottomIndex]) {
const Tile *below = currentLayer->cellAt(bottomPoint).tile;
if (bottomEdge(paste) != topEdge(below))
transitionList.append(QPoint(x, y + 1));
transitionList.append(bottomPoint);
}
if (x > 0 && !checked[i - 1]) {
const Tile *left = currentLayer->cellAt(x - 1, y).tile;
if (currentLayer->contains(leftPoint) && !checked[leftIndex]) {
const Tile *left = currentLayer->cellAt(leftPoint).tile;
if (leftEdge(paste) != rightEdge(left))
transitionList.append(QPoint(x - 1, y));
transitionList.append(leftPoint);
}
if (x < layerWidth - 1 && !checked[i + 1]) {
const Tile *right = currentLayer->cellAt(x + 1, y).tile;
if (currentLayer->contains(rightPoint) && !checked[rightIndex]) {
const Tile *right = currentLayer->cellAt(rightPoint).tile;
if (rightEdge(paste) != leftEdge(right))
transitionList.append(QPoint(x + 1, y));
transitionList.append(rightPoint);
}
}

Expand Down

0 comments on commit 18d633b

Please sign in to comment.