Skip to content

Commit

Permalink
Added support for a margin around a tileset image
Browse files Browse the repository at this point in the history
The margin attribute has been added to the tileset element, next to the
tile spacing attribute. This basically implements Flyspray task 79, which was
about adding support for an offset. The margin also applies to the bottom and
right sides, however.
  • Loading branch information
bjorn committed Aug 31, 2008
1 parent 7805823 commit 4f7fc90
Show file tree
Hide file tree
Showing 12 changed files with 77 additions and 37 deletions.
1 change: 1 addition & 0 deletions CHANGES
@@ -1,3 +1,4 @@
* Added support for a margin around a tileset image
* Fixed automatically adding extension to tileset Save As... dialog
* Fixed saving/loading of layers with an origin other than 0,0
* Fixed map resize to apply the offset to layers not matching the map bounds
Expand Down
7 changes: 0 additions & 7 deletions SUGGESTIONS
Expand Up @@ -19,13 +19,6 @@ State: To be discussed
Problems: The engine the user is using will still need to understand the
way Tiled uses the coordinates.

- 04 --------------------------------------------------------------------------
Suggestor: Ahmed Mohombe <amohombe@yahoo.com>
Date: 08/04/04
Summary: Allow tilesets with a border to be used by Tiled. Borders around
the tileset image are used by FreeCiv for example.
State: To be implemented (offset attributes, task #79)

- 06 --------------------------------------------------------------------------
Suggestor: Ahmed Mohombe <amohombe@yahoo.com>
Date: 08/04/04
Expand Down
2 changes: 1 addition & 1 deletion examples/tilespacing-test.tmx
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE map SYSTEM "http://mapeditor.org/dtd/1.0/map.dtd">
<map version="1.0" orientation="orthogonal" width="32" height="32" tilewidth="32" tileheight="32">
<tileset name="Desert" firstgid="1" tilewidth="32" tileheight="32" spacing="1">
<tileset name="Desert" firstgid="1" tilewidth="32" tileheight="32" spacing="1" margin="1">
<image source="tmw_desert_spacing.png"/>
</tileset>
<!-- Layer data is compressed (GZip) binary data, encoded in Base64 -->
Expand Down
Binary file modified examples/tmw_desert_spacing.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 3 additions & 3 deletions src/tiled/core/MapObject.java
Expand Up @@ -22,7 +22,7 @@ public class MapObject implements Cloneable
{
private Properties properties = new Properties();

protected float x, y;
protected int x, y;
protected Rectangle bounds = new Rectangle();
protected boolean bVisible = true;
protected String name = "Object";
Expand Down Expand Up @@ -82,11 +82,11 @@ public void translate(int x, int y) {
}

public int getX() {
return (int) x;
return x;
}

public int getY() {
return (int) y;
return y;
}

public String getName() {
Expand Down
14 changes: 12 additions & 2 deletions src/tiled/core/TileSet.java
Expand Up @@ -46,6 +46,7 @@ public class TileSet
private TileCutter tileCutter;
private Rectangle tileDimensions;
private int tileSpacing;
private int tileMargin;
private int tilesPerRow;
private String externalSource;
private File tilebmpFile;
Expand Down Expand Up @@ -110,8 +111,8 @@ public void importTileBitmap(String imgFilename, TileCutter cutter)
*/
private void importTileBitmap(BufferedImage tilebmp, TileCutter cutter)
{
assert(tilebmp != null);
assert(cutter != null);
assert tilebmp != null;
assert cutter != null;

tileCutter = cutter;
tileSetImage = tilebmp;
Expand All @@ -122,6 +123,7 @@ private void importTileBitmap(BufferedImage tilebmp, TileCutter cutter)
if (cutter instanceof BasicTileCutter) {
BasicTileCutter basicTileCutter = (BasicTileCutter) cutter;
tileSpacing = basicTileCutter.getTileSpacing();
tileMargin = basicTileCutter.getTileMargin();
tilesPerRow = basicTileCutter.getTilesPerRow();
}

Expand Down Expand Up @@ -409,6 +411,14 @@ public int getTileSpacing() {
return tileSpacing;
}

/**
* Returns the margin around the tiles on the tileset image.
* @return the margin in pixels around the tiles on the tileset image
*/
public int getTileMargin() {
return tileMargin;
}

/**
* Returns the number of tiles per row in the original tileset image.
* @return the number of tiles per row in the original tileset image.
Expand Down
9 changes: 5 additions & 4 deletions src/tiled/io/xml/XMLMapTransformer.java
Expand Up @@ -322,9 +322,10 @@ private TileSet unmarshalTileset(Node t) throws Exception {
return ext;
}
else {
int tileWidth = getAttribute(t, "tilewidth", map != null ? map.getTileWidth() : 0);
int tileHeight = getAttribute(t, "tileheight", map != null ? map.getTileHeight() : 0);
int tileSpacing = getAttribute(t, "spacing", 0);
final int tileWidth = getAttribute(t, "tilewidth", map != null ? map.getTileWidth() : 0);
final int tileHeight = getAttribute(t, "tileheight", map != null ? map.getTileHeight() : 0);
final int tileSpacing = getAttribute(t, "spacing", 0);
final int tileMargin = getAttribute(t, "margin", 0);

TileSet set = new TileSet();

Expand Down Expand Up @@ -369,7 +370,7 @@ private TileSet unmarshalTileset(Node t) throws Exception {
}

set.importTileBitmap(sourcePath, new BasicTileCutter(
tileWidth, tileHeight, tileSpacing, 0));
tileWidth, tileHeight, tileSpacing, tileMargin));
} else {
Image image = unmarshalImage(child, tilesetBaseDir);
String idValue = getAttributeValue(child, "id");
Expand Down
6 changes: 5 additions & 1 deletion src/tiled/io/xml/XMLMapWriter.java
Expand Up @@ -216,10 +216,14 @@ private static void writeTileset(TileSet set, XMLWriter w, String wp)
w.writeAttribute("tilewidth", set.getTileWidth());
w.writeAttribute("tileheight", set.getTileHeight());

int tileSpacing = set.getTileSpacing();
final int tileSpacing = set.getTileSpacing();
final int tileMargin = set.getTileMargin();
if (tileSpacing != 0) {
w.writeAttribute("spacing", tileSpacing);
}
if (tileMargin != 0) {
w.writeAttribute("margin", tileMargin);
}
}

if (set.getBaseDir() != null) {
Expand Down
38 changes: 29 additions & 9 deletions src/tiled/mapeditor/dialogs/NewTilesetDialog.java
Expand Up @@ -42,9 +42,11 @@ public class NewTilesetDialog extends JDialog implements ChangeListener
private TileSet newTileset;
private IntegerSpinner tileWidth, tileHeight;
private IntegerSpinner tileSpacing;
private IntegerSpinner tileMargin;
private JTextField tilesetName;
private JTextField tilebmpFile;
private JLabel spacingLabel;
private JLabel marginLabel;
private JLabel tilebmpFileLabel, cutterLabel;
private JCheckBox tilebmpCheck;
private JCheckBox transCheck;
Expand All @@ -63,6 +65,7 @@ public class NewTilesetDialog extends JDialog implements ChangeListener
private static final String TILE_WIDTH_LABEL = Resources.getString("dialog.newtileset.tilewidth.label");
private static final String TILE_HEIGHT_LABEL = Resources.getString("dialog.newtileset.tileheight.label");
private static final String TILE_SPACING_LABEL = Resources.getString("dialog.newtileset.tilespacing.label");
private static final String TILE_MARGIN_LABEL = Resources.getString("dialog.newtileset.tilemargin.label");
private static final String IMAGE_LABEL = Resources.getString("dialog.newtileset.image.label");
private static final String UNTITLED_FILE = Resources.getString("general.file.untitled");
private static final String TILESET_IMG_LABEL = Resources.getString("dialog.newtileset.tilesetimgref.label");
Expand Down Expand Up @@ -96,20 +99,23 @@ private void init() {
JLabel tileWidthLabel = new JLabel(TILE_WIDTH_LABEL);
JLabel tileHeightLabel = new JLabel(TILE_HEIGHT_LABEL);
spacingLabel = new JLabel(TILE_SPACING_LABEL);
marginLabel = new JLabel(TILE_MARGIN_LABEL);
tilebmpFileLabel = new JLabel(IMAGE_LABEL);
cutterLabel = new JLabel("Tile Cutter: ");

tilesetName = new JTextField(UNTITLED_FILE);
tileWidth = new IntegerSpinner(map.getTileWidth(), 1, 1024);
tileHeight = new IntegerSpinner(map.getTileHeight(), 1, 1024);
tileSpacing = new IntegerSpinner(0, 0);
tileMargin = new IntegerSpinner(0, 0);
tilebmpFile = new JTextField(10);
tilebmpFile.setEnabled(false);

nameLabel.setLabelFor(tilesetName);
tileWidthLabel.setLabelFor(tileWidth);
tileHeightLabel.setLabelFor(tileHeight);
spacingLabel.setLabelFor(tileSpacing);
marginLabel.setLabelFor(tileMargin);
tilebmpFileLabel.setLabelFor(tilebmpFile);

tileWidthLabel.setEnabled(false);
Expand Down Expand Up @@ -173,7 +179,7 @@ private void init() {
c.insets = new Insets(5, 0, 0, 0);
c.anchor = GridBagConstraints.EAST;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 2;
c.gridwidth = 4;
tilebmpPanel.add(tilebmpCheck, c);
c.gridy = 1;
c.gridwidth = 1;
Expand All @@ -191,7 +197,9 @@ private void init() {
c.weightx = 1;
c.insets = new Insets(5, 0, 0, 0);
c.fill = GridBagConstraints.HORIZONTAL;
c.gridwidth = 3;
tilebmpPanel.add(tilebmpPathPanel, c);
c.gridwidth = 1;
c.gridy = 2;
tilebmpPanel.add(tileSpacing, c);
/*
Expand All @@ -200,8 +208,17 @@ private void init() {
*/
c.gridx = 0;
c.gridy = 4;
c.gridwidth = 2;
c.gridwidth = 4;
tilebmpPanel.add(tileColorPanel, c);
c.gridx = 2;
c.gridy = 2;
c.gridwidth = 1;
c.weightx = 0;
c.insets = new Insets(5, 5, 0, 0);
tilebmpPanel.add(marginLabel, c);
c.gridx = 3;
c.weightx = 1;
tilebmpPanel.add(tileMargin, c);
c.gridx = 1;
c.gridwidth = 1;

Expand Down Expand Up @@ -313,10 +330,10 @@ public TileSet create() {
return newTileset;
}

public TileCutter getCutter(int w, int h, int s) {
public TileCutter getCutter(int w, int h, int spacing, int margin) {
final String selectedItem = (String) cutterBox.getSelectedItem();
if (selectedItem.equalsIgnoreCase("basic")) {
return new BasicTileCutter(w, h, s, 0);
return new BasicTileCutter(w, h, spacing, margin);
} else if (selectedItem.equalsIgnoreCase("border")) {
return new BorderTileCutter();
}
Expand All @@ -330,10 +347,11 @@ private void createSetAndDispose() {
newTileset.setDefaultProperties(defaultSetProperties);

if (tilebmpCheck.isSelected()) {
String file = tilebmpFile.getText();
int spacing = tileSpacing.intValue();
int width = tileWidth.intValue();
int height = tileHeight.intValue();
final String file = tilebmpFile.getText();
final int spacing = tileSpacing.intValue();
final int margin = tileMargin.intValue();
final int width = tileWidth.intValue();
final int height = tileHeight.intValue();

try {
if (transCheck.isSelected()) {
Expand All @@ -342,7 +360,7 @@ private void createSetAndDispose() {
}

newTileset.importTileBitmap(file,
getCutter(width, height, spacing));
getCutter(width, height, spacing, margin));
}
catch (IOException e) {
JOptionPane.showMessageDialog(this, e.getLocalizedMessage(),
Expand Down Expand Up @@ -386,7 +404,9 @@ private void setUseTileBitmap(boolean value) {
tilebmpFileLabel.setEnabled(value);
browseButton.setEnabled(value);
tileSpacing.setEnabled(value);
tileMargin.setEnabled(value);
spacingLabel.setEnabled(value);
marginLabel.setEnabled(value);
transCheck.setEnabled(value);
colorButton.setEnabled(value && transCheck.isSelected());
/*
Expand Down
1 change: 1 addition & 0 deletions src/tiled/mapeditor/resources/gui.properties
Expand Up @@ -110,6 +110,7 @@ dialog.newtileset.name.label=Tileset name:
dialog.newtileset.tileheight.label=Tile height:
dialog.newtileset.tilesetimgref.label=Reference tileset image
dialog.newtileset.tilespacing.label=Tile spacing:
dialog.newtileset.tilemargin.label=Margin:
dialog.newtileset.tilewidth.label=Tile width:
dialog.newtileset.title=New Tileset
dialog.newtileset.usetransparentcolor.label=Use transparent color
Expand Down
1 change: 1 addition & 0 deletions src/tiled/mapeditor/resources/map.dtd
Expand Up @@ -71,6 +71,7 @@
tilewidth CDATA #IMPLIED
tileheight CDATA #IMPLIED
spacing CDATA #IMPLIED
margin CDATA #IMPLIED
>

<!--
Expand Down
29 changes: 19 additions & 10 deletions src/tiled/mapeditor/util/cutter/BasicTileCutter.java
Expand Up @@ -18,7 +18,7 @@

/**
* Cuts tiles from a tileset image according to a regular rectangular pattern.
* Supports a variable spacing between tiles and an offset from the origin.
* Supports a variable spacing between tiles and a margin around them.
*
* @version $Id$
*/
Expand All @@ -29,15 +29,15 @@ public class BasicTileCutter implements TileCutter
private final int tileWidth;
private final int tileHeight;
private final int tileSpacing;
private final int offset;
private final int tileMargin;

public BasicTileCutter(int tileWidth, int tileHeight, int tileSpacing,
int offset)
int tileMargin)
{
this.tileWidth = tileWidth;
this.tileHeight = tileHeight;
this.tileSpacing = tileSpacing;
this.offset = offset;
this.tileMargin = tileMargin;

reset();
}
Expand All @@ -51,13 +51,13 @@ public void setImage(BufferedImage image) {
}

public Image getNextTile() {
if (nextY + tileHeight <= image.getHeight()) {
if (nextY + tileHeight + tileMargin <= image.getHeight()) {
BufferedImage tile =
image.getSubimage(nextX, nextY, tileWidth, tileHeight);
nextX += tileWidth + tileSpacing;

if (nextX + tileWidth > image.getWidth()) {
nextX = offset;
if (nextX + tileWidth + tileMargin > image.getWidth()) {
nextX = tileMargin;
nextY += tileHeight + tileSpacing;
}

Expand All @@ -68,8 +68,8 @@ public Image getNextTile() {
}

public void reset() {
nextX = offset;
nextY = offset;
nextX = tileMargin;
nextY = tileMargin;
}

public Dimension getTileDimensions() {
Expand All @@ -84,11 +84,20 @@ public int getTileSpacing() {
return tileSpacing;
}

/**
* Returns the margin around the tile images.
* @return the margin around the tile images.
*/
public int getTileMargin() {
return tileMargin;
}

/**
* Returns the number of tiles per row in the tileset image.
* @return the number of tiles per row in the tileset image.
*/
public int getTilesPerRow() {
return (image.getWidth() + tileSpacing) / (tileWidth + tileSpacing);
return (image.getWidth() - 2 * tileMargin + tileSpacing) /
(tileWidth + tileSpacing);
}
}

0 comments on commit 4f7fc90

Please sign in to comment.