Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/workflows/java.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Build libtiled-java

on:
push:
branches:
- master
paths:
- 'util/java/**'
- '.github/workflows/java.yml'
pull_request:
paths:
- 'util/java/**'
- '.github/workflows/java.yml'

jobs:
build:

runs-on: ubuntu-24.04

steps:
- name: Checkout repository
uses: actions/checkout@v6

- name: Setup Java
uses: actions/setup-java@v5
with:
distribution: temurin
java-version: 21
cache: maven

- name: Build and test
run: mvn --batch-mode clean install
working-directory: util/java
28 changes: 28 additions & 0 deletions util/java/libtiled-java/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,34 @@ Add the following to your `build.sbt`:
libraryDependencies += "org.mapeditor" % "libtiled" % "x.y.z"
```

## Excluding unused dependencies

libtiled depends on [zstd-jni](https://github.com/luben/zstd-jni) to read and
write zstd-compressed layer data and on
[jsvg](https://github.com/weisJ/jsvg) to render SVG tilesets. If your project
uses neither, you can exclude them to reduce its size:

```xml
<dependency>
<groupId>org.mapeditor</groupId>
<artifactId>libtiled</artifactId>
<version>x.y.z</version>
<exclusions>
<exclusion>
<groupId>com.github.luben</groupId>
<artifactId>zstd-jni</artifactId>
</exclusion>
<exclusion>
<groupId>com.github.weisj</groupId>
<artifactId>jsvg</artifactId>
</exclusion>
</exclusions>
</dependency>
```

Loading a zstd-compressed map or an SVG tileset without the respective
dependency fails with an error naming the missing dependency.

## Building

To make libtiled.jar, install [Apache Maven](http://maven.apache.org/) and run the following command:
Expand Down
10 changes: 10 additions & 0 deletions util/java/libtiled-java/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,16 @@
</scm>

<dependencies>
<dependency>
<groupId>com.github.luben</groupId>
<artifactId>zstd-jni</artifactId>
<version>1.5.6-8</version>
</dependency>
<dependency>
<groupId>com.github.weisj</groupId>
<artifactId>jsvg</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
*/
package org.mapeditor.core;

import java.awt.image.BufferedImage;
import java.util.List;

/**
* Animated tiles take advantage of the Sprite class internally to handle
* animation using an array of tiles.
Expand All @@ -39,7 +42,10 @@
*/
public class AnimatedTile extends Tile {

private static final int DEFAULT_FRAME_DURATION_MS = 100;

private Sprite sprite;
private final long animationStartTimeMs = System.currentTimeMillis();

/**
* Constructor for AnimatedTile.
Expand Down Expand Up @@ -111,4 +117,54 @@ public int countKeys() {
public Sprite getSprite() {
return sprite;
}

/** {@inheritDoc} */
@Override
public BufferedImage getImage() {
final Animation animation = getAnimation();
if (animation != null && animation.getFrame() != null && !animation.getFrame().isEmpty()) {
final TileSet tileSet = getTileSet();
if (tileSet == null) {
return super.getImage();
}

final List<Frame> frames = animation.getFrame();
int totalDuration = 0;
for (Frame frame : frames) {
int duration = frame.getDuration() != null ? frame.getDuration() : DEFAULT_FRAME_DURATION_MS;
if (duration > 0) {
totalDuration += duration;
}
}
if (totalDuration <= 0) {
return super.getImage();
}

long elapsed = (System.currentTimeMillis() - animationStartTimeMs) % totalDuration;
if (elapsed < 0) {
// The system clock may move backwards.
elapsed += totalDuration;
}
long time = 0;
for (Frame frame : frames) {
int duration = frame.getDuration() != null ? frame.getDuration() : DEFAULT_FRAME_DURATION_MS;
if (duration <= 0) {
duration = DEFAULT_FRAME_DURATION_MS;
}
time += duration;
if (elapsed < time) {
Tile frameTile = tileSet.getTile(frame.getTileid());
if (frameTile != null && frameTile != this) {
return frameTile.getImage();
}
break;
}
}
}

if (sprite != null && sprite.getCurrentKey() != null) {
return sprite.getCurrentFrame().getImage();
}
return super.getImage();
}
}
37 changes: 37 additions & 0 deletions util/java/libtiled-java/src/main/java/org/mapeditor/core/Map.java
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,43 @@ public class Map extends MapData implements Iterable<MapLayer> {

private String filename;

private Integer editorChunkWidth;
private Integer editorChunkHeight;
private String exportTarget;
private String exportFormat;

public Integer getEditorChunkWidth() {
return editorChunkWidth;
}

public void setEditorChunkWidth(Integer editorChunkWidth) {
this.editorChunkWidth = editorChunkWidth;
}

public Integer getEditorChunkHeight() {
return editorChunkHeight;
}

public void setEditorChunkHeight(Integer editorChunkHeight) {
this.editorChunkHeight = editorChunkHeight;
}

public String getExportTarget() {
return exportTarget;
}

public void setExportTarget(String exportTarget) {
this.exportTarget = exportTarget;
}

public String getExportFormat() {
return exportFormat;
}

public void setExportFormat(String exportFormat) {
this.exportFormat = exportFormat;
}

/**
* Constructor for Map.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import org.mapeditor.util.ImageHelper;

import jakarta.xml.bind.annotation.XmlAccessType;
import jakarta.xml.bind.annotation.XmlAccessorType;

Expand All @@ -62,6 +63,7 @@ public class MapObject extends MapObjectData implements Cloneable {
private boolean flipHorizontal;
private boolean flipVertical;
private boolean flipDiagonal;
private boolean rotatedHexagonal120;

/**
* Constructor for MapObject.
Expand All @@ -72,8 +74,6 @@ public MapObject() {
this.name = "";
this.type = "";
this.imageSource = "";
this.flipHorizontal = false;
this.flipVertical = false;
}

/**
Expand Down Expand Up @@ -182,9 +182,9 @@ public void setImageSource(String source) {
imageSource = source;

// Attempt to read the image
if (imageSource.length() > 0) {
if (!imageSource.isEmpty()) {
try {
image = ImageIO.read(new File(imageSource));
image = ImageHelper.readImage(new File(imageSource));
} catch (IOException e) {
image = null;
}
Expand Down Expand Up @@ -222,6 +222,9 @@ public void setTile(Tile tile) {
public boolean getFlipDiagonal() { return flipDiagonal; }
public void setFlipDiagonal(boolean flip) { this.flipDiagonal = flip; }

public boolean getRotatedHexagonal120() { return rotatedHexagonal120; }
public void setRotatedHexagonal120(boolean rotated) { this.rotatedHexagonal120 = rotated; }

/**
* Returns the image to be used when drawing this object. This image is
* scaled to the size of the object.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,36 @@ public void setProperty(String name, String value) {
properties.add(property);
}

/**
* setProperty with type.
*
* @param name a {@link java.lang.String} object.
* @param value a {@link java.lang.String} object.
* @param type a {@link org.mapeditor.core.PropertyType} object.
*/
public void setProperty(String name, String value, PropertyType type) {
setProperty(name, value, type, null);
}

/**
* setProperty with type and custom property type name.
*
* @param name a {@link java.lang.String} object.
* @param value a {@link java.lang.String} object.
* @param type a {@link org.mapeditor.core.PropertyType} object.
* @param propertyTypeName the custom type name (optional).
*/
public void setProperty(String name, String value, PropertyType type, String propertyTypeName) {
Property property = new Property();
property.setName(name);
property.setValue(value);
property.setType(type);
if (propertyTypeName != null) {
property.setPropertyTypeName(propertyTypeName);
}
properties.add(property);
}

/**
* getProperty.
*
Expand Down Expand Up @@ -112,9 +142,7 @@ public boolean isEmpty() {
* @return a {@link java.util.List} object.
*/
public List<String> keySet() {
List<String> keys = new ArrayList<>();
properties.forEach(property -> keys.add(property.getName()));
return keys;
return properties.stream().map(Property::getName).collect(java.util.stream.Collectors.toList());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ public Sprite() {
* @param frames an array of {@link org.mapeditor.core.Tile} objects.
*/
public Sprite(Tile[] frames) {
this();
setFrames(frames);
}

Expand All @@ -172,6 +173,7 @@ public Sprite(Tile[] frames) {
* @param totalFrames a int.
*/
public Sprite(Image image, int fpl, int border, int totalFrames) {
this();
Tile[] frames = null;
this.fpl = fpl;
borderWidth = border;
Expand Down
22 changes: 22 additions & 0 deletions util/java/libtiled-java/src/main/java/org/mapeditor/core/Tile.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,28 @@ public void setSource(String source) {
this.source = source;
}

/**
* Sets the collision object group for this tile.
*
* @param og the object group defining collision shapes
*/
public void setObjectGroup(ObjectGroup og) {
getObjectgroup().clear();
getObjectgroup().add(og);
}

/**
* Gets the collision object group for this tile, if any.
*
* @return the first ObjectGroup, or null
*/
public ObjectGroup getCollisionObjectGroup() {
if (objectgroup != null && !objectgroup.isEmpty()) {
return (ObjectGroup) objectgroup.get(0);
}
return null;
}

/** {@inheritDoc} */
@Override
public Properties getProperties() {
Expand Down
Loading
Loading